tags:

views:

12027

answers:

10

Please indicate your best practices for building XML using C#.

Edit:

With the help of Shog9, I just learned about the "community wiki" feature, and happily turned it on.

If you like a particular answer, vote it up. If you don't like a particular answer, feel free to shake your fist violently in the air and vote it down.

+51  A: 

It depends on the scenario. XmlSerializer is certainly one way, and has the advantage of mapping directly to an object model. In .NET 3.5, XDocument etc are also very friendly. If the size is very large, then XmlWriter is your friend.

For an XDocument example:

    Console.WriteLine(
        new XElement("Foo",
            new XAttribute("Bar", "some & value"),
            new XElement("Nested", "data")));

Or the same with XmlDocument:

    XmlDocument doc = new XmlDocument();
    XmlElement el = (XmlElement)doc.AppendChild(doc.CreateElement("Foo"));
    el.SetAttribute("Bar", "some & value");
    el.AppendChild(doc.CreateElement("Nested")).InnerText = "data";
    Console.WriteLine(doc.OuterXml);

If you are writing a large stream of data, then any of the DOM approaches (such as XmlDocument/XDocument etc) will quickly take a lot of memory. So if you are writing a 100MB xml file from csv, you might consider XmlWriter; this is more primative (a write-once firehose), but very efficient (imagine a big loop here):

    XmlWriter writer = XmlWriter.Create(Console.Out);
    writer.WriteStartElement("Foo");
    writer.WriteAttributeString("Bar", "Some & value");
    writer.WriteElementString("Nested", "data");
    writer.WriteEndElement();

Finally, via XmlSerializer:

    [Serializable]
    public class Foo
    {
        [XmlAttribute]
        public string Bar { get; set; }
        public string Nested { get; set; }
    }
    ...
    Foo foo = new Foo
    {
        Bar = "some & value",
        Nested = "data"
    };
    new XmlSerializer(typeof(Foo)).Serialize(Console.Out, foo);

This is a nice model for mapping to classes etc; however, it might be overkill if you are doing something simple (or if the desired xml doesn't really have a direct correlation to the object model). Another issue with XmlSerializer is that it doesn't like to serialize immutable types : everything must have a public getter and setter (unless you do it all yourself by implementing IXmlSerializable, in which case you haven't gained much by using XmlSerializer).

Marc Gravell
I'm not sure what you mean by your last comment "If the size is very large, then XmlReader is your friend." Can you elaborate?
Dan Esparza
sure - I'll edit
Marc Gravell
I think you mean XmlWriter rather than XmlReader :), but other than that great answer.
Greg Beech
Don't forget about XStreamingElement, http://msdn.microsoft.com/en-us/library/system.xml.linq.xstreamingelement.aspx. :)
Todd White
@Toll - thanks; I knew I'd missed one...
Marc Gravell
+3  A: 

I would give XLINQ (read: LINQ to XML) a try. It's easy, intuitive and is easily editable.

Chad Moran
I found this find really useful, thanks Chad. While there are times serialization is the right answer, there are plenty of scenarios where complex xml generation in code is the right answer. It is a shame C# doesnt have the same inline Xml capababilities as VB.net. Thanks again.
Russell
+3  A: 

XmlWriter is the fastest way to write good XML. XDocument, XMLDocument and some others works good aswell, but are not optimized for writing XML. If you want to write the XML as fast as possible, you should definitely use XmlWriter.

vimpyboy
A: 

For simple things, I just use the XmlDocument/XmlNode/XmlAttribute classes and XmlDocument DOM found in System.XML.

It generates the XML for me, I just need to link a few items together.

However, on larger things, I use XML serialization.

FlySwat
+3  A: 

Also check out the Mark Resmussen's XmlDocument fluent interface, which really provides easy to type/read XML output.

Rob Walker
+1  A: 

For simple cases, I would also suggest looking at XmlOutput a fluent interface for building Xml.

XmlOutput is great for simple Xml creation with readable and maintainable code, while generating valid Xml. The orginal post has some great examples.

Todd
+1  A: 

In the past I have created my XML Schema, then used a tool to generate C# classes which will serialize to that schema. The XML Schema Definition Tool is one example

http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx

Bob
A: 

As above.

I use stringbuilder.append().

Very straightforward, and you can then do xmldocument.load(strinbuilder object as parameter).

You will probably find yourself using string.concat within the append parameter, but this is a very straightforward approach.

dotnetdev
Except when you forget to encode something properly and write illegal Xml.
Robert Paulson
This answer got absolutely slammed, but based upon this question I took a look at one of my own implementations where I build XML. For my particular project I consistently found that building via StringBuilder resulted in processing times 10% faster than using XDocument/XmlWriter. But, I feel comfortable with XML, and that's for my particular project. (For reference, final XML sizes are around 3.4 MB, with over 8000 lines.)
James Skemp
+9  A: 

The best thing hands down that I have tried is LINQ to XSD (which is unknown to most developers). You give it an XSD Schema and it generates a perfectly mapped complete strongly-typed object model (based on LINQ to XML) for you in the background, which is really easy to work with - and it updates and validates your object model and XML in real-time. While it's still "Preview", I have not encountered any bugs with it.

If you have an XSD Schema that looks like this:

  <xs:element name="RootElement">
     <xs:complexType>
      <xs:sequence>
        <xs:element name="Element1" type="xs:string" />
        <xs:element name="Element2" type="xs:string" />
      </xs:sequence>
       <xs:attribute name="Attribute1" type="xs:integer use="optional" />
       <xs:attribute name="Attribute2" type="xs:boolean" use="required" />
     </xs:complexType>
  </xs:element>

Then you can simply build XML like this:

RootElement rootElement = new RootElement;
rootElement.Element1 = "Element1";
rootEleemnt.Element2 = "Element2";
rootEleemnt.Attribute1 = 5;
rootEleemnt.Attribute2 = true;

Or simply load an XML from file like this:

RootElement rootElement = RootElement.Load(filePath);

Or save it like this:

rootElement.Save(string);
rootElement.Save(textWriter);
rootElement.Save(xmlWriter);

rootElement.Untyped also yields the element in form of a XElement (from LINQ to XML).

Hermann
Thanks for the heads up!
Dan Esparza
Note that as of now, this project seems to be pretty close to death.
James Skemp
@James: `[citation-needed]`
Robert Harvey
@Robert Harvey: Check the date of my comment. Three days later the commits/fixes started rolling in. Honestly, I'm glad the project turned around, as now I can look at it as a feasible option.
James Skemp
A: 
new XElement("Foo",
       from s in nameValuePairList
       select
             new XElement("Bar",
                  new XAttribute("SomeAttr", "SomeAttrValue"),
                          new XElement("Name", s.Name),
                          new XElement("Value", s.Value)
                         )
            );
Vincent