开发者

XML and C# - WriteEndElement

I'm using System.Xml to create an XML document in C#

My question is hopefully a simple one, do I need to use the WriteEndElement to close an XML tag?

For example, I have found that the following code will compile with or without 'writer.WriteEndElement();' and produce the same XML either way, how开发者_如何学Goever if I put 'writer.WriteEndElement();' twice, the program throws an exception.

writer.WriteStartElement("CustomerNo");
writer.WriteString("12345");
writer.WriteEndElement();

I'm not lazy and don't mind putting this in where it needs to be if this is how it's supposed to be, I just need some guidance here.

Thanks

John


Generally speaking: Yes, for each WriteStartElement() there must be a matching WriteEndElement().

Think of the containment hierarchy as a stack - the Starts ("pushes") and Ends ("pops") must balance. If you try to "pop" beyond the end, it's a failure and an exception is thrown, like you describe.

As an example, to write a B element within the A element:

WriteStartElement("A");
WriteStartElement("B");
// ... attributes or content added here will become part af B element
WriteEndElement(); // Closes the open B element.
WriteEndElement(); // Closes the open A element.

Update: As @Sam points out in another answer, when - as in the example you give - you want to only write out simple content elements (no attributes or child elements), you may want to take a look at the convenience method WriteElementString(), which automatically wraps the content in start/end tags.

Hope this helps.


I agree with Cumbayah's answer, however you can alternatively use XmlTextWriter's WriteElementString(string,string) method if you just want an element with a value inside (no attributes, no child elements).

Example:

writer.WriteElementString("CustomerNo", "12345");

I highly recommend this as it will save a lot of space and make the code more readable.

Also, to really go the extra mile you could do:

writer.WriteElementString(XmlConvert.EncodeName("CustomerNo"), "12345");

Encode and Decode XML Element and Attribute Names and ID Values

The XmlTextWriter class does not perform character checks by default. For example, the code WriteElementString("Order Detail", "My order"), produces an invalid element of My order.

To encode the element value, the correct encoding is writer.WriteElementString(XmlConvert.EncodeName("Order Detail"), "My order") which produces the valid element My order.


Somewhere, there's a call to XmlWriter.Close, which—among other things—makes sure

Any elements or attributes left open are automatically closed.

If you didn't call XmlWriter.Close explicitly, C# will do so itself (via XmlWriter.Dispose after the object goes out of scope)


I use XDoument to create my XM Files, here is what I use to create an XML FIle:

XDocument doc = new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                        new XComment(" "),
                        new XComment("My Company, Inc"),
                        new XComment("Comment XML File\n"),
                        new XComment("Don't edit this file with first consulting with Me."),
                        new XComment(" "),
                        new XComment(" "),
                        new XElement("Main1",
                            new XElement("Application",
                                new XElement("RemoteServer", "127.0.0.1"),
                                new XElement("AppVersion", "1.00.0000"),"
                                new XElement("UpdateNecessary", "No")
                                ),
                        new XElement("Departments",
                            new XElement("Item", "Sales"),
                                new XElement("Item", "Shipping"),
                                new XElement("Item", "Human Resources"),
                                new XElement("Item", "Technical Support")
                                )
                                ));


I would suggest using XMLSerialization in C# to first create a ObjectModel, which can be filled easily, and afterwards you can just save it down to XML.
Just Tag your ObjectModel Serializable and use Datatype which can be serialized or Implement ISerializable to do so.
Any Problems with different stylings, or even structural changes can be handled smooth via the ObjectModel. And the XMLSerializer is doing the job for you.
If you can't use an ObjectModel, i would suggest using an XmlDocument
To Create the Nodes. Here you can also use NamespaceTables and as far as i know, you can't create corrupt XML Files.


Response.Clear();
Response.ContentType = "application/rss+xml";
XmlTextWriter writer = new XmlTextWriter(@"E:\product.xml", 
System.Text.Encoding.UTF8);

writer.WriteStartDocument(true);
writer.WriteStartElement("rss");
writer.WriteAttributeString("version", "2.0");
writer.WriteStartElement("produts");

writer.Formatting = Formatting.Indented;
writer.Indentation = 2; 

createNode("1", "Product 1", "1000", writer);
createNode("2", "Product 2", "2000", writer);
createNode("3", "Product 3", "3000", writer);
createNode("4", "Product 4", "4000", writer);

writer.WriteEndElement();
writer.WriteEndElement();
writer.Close();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜