tags:

views:

412

answers:

13

There seem to be many options to create an XML document in .NET. What's the best approach?

+3  A: 

I would personally use LINQ to XML if I possibly could. It's much nicer than the DOM API. Of course, it does rely on you using .NET 3.5...

Note that your String.Format solution breaks down if you have any text which would need escaping. Admittedly I can't think of any car makes and models including & or < etc, but in a more general case it's a real issue.

Jon Skeet
Chrysler Town )
Andrew Bullock
A: 

The string.format (or any other form of string concatenation) is clearly a code smell, and in practice is considerably more opaque, more prone to human error, harder to break-up and so less maintainable, and slower than the DOM methods.

I strongly advise the DOM approach.

annakata
+4  A: 

XmlWriter has a nice interface for creating a document in a streaming, forward-only style. It works best if you have a recursive structure that you need to map into XML.

I would only use the DOM API as a last resort. As Jon says, LINQ to XML is another way to go. Whatever you do, though, don't fall back to string formatting, as there are subtleties like namespaces, entity quoting, attribute quoting, etc. that you'd need to get right.

Barry Kelly
A: 

Have you considered using XML Serilization, and serilizing your Class to an XML File

+4  A: 

An alternate method is to use Xml Serialization: Just create classes that represents your (complex) elements, fill with public properties that represent the contents of these elements, possibly give additional info about the layout using attributes: [XmlElement()], [XmlAttribute()],... And use XmlSerializer to create the doc:

public class Car
{
  public string Make;
  public string Model;
}


public class Cars
{
  [XmlElement("Car")]
  public Car[] cars;
}


class Program
{
  public static void Save(Cars cars, string sFilename)
  {
    try
    {
      XmlSerializer ser = new XmlSerializer(cars.GetType());
      FileStream fs = new FileStream(sFilename, FileMode.Create);
      ser.Serialize(fs, cars);
      fs.Close();
    }
    catch (Exception ex)
    { // Failed to save data to disk.
      Debug.WriteLine(string.Format("Failed to save contents of {0}: {1}", sFilename ,ex.Message));
    }
  }
}
Serge - appTranslator
+5  A: 

If you simply need to generate XML (no parsing or editing needed) the fastest way to do this is using an XmlWriter (It's more elegant and faster than your second example using strings and much less error prone because you do not have to worry about keeping your document well-formed):

    XmlWriter writer = null;

    try {

       // Create an XmlWriterSettings object with the correct options. 
       XmlWriterSettings settings = new XmlWriterSettings();
       settings.Indent = true;
       settings.IndentChars = ("\t");
       settings.OmitXmlDeclaration = true;

       // Create the XmlWriter object and write some content.
       writer = XmlWriter.Create("data.xml", settings);
       writer.WriteStartElement("book");
       writer.WriteElementString("item", "tesing");
       writer.WriteEndElement();

       writer.Flush();

     } 
     finally  {
        if (writer != null)
          writer.Close();
     }

If you already have an object model to serialize, you could think of using an XmlSerializer, which is however - at least from my experience - much slower than XmlWriter and is only easy to use on simple object models.

0xA3
A: 

If you have a schema file available for your XML document, you could use the xsd tool to generate the classes for you and then use serialization to read and write the XML files.

KevB
+1  A: 

I haven't done it yet, but VB's XML Literals.

kenny
A: 

The current project I'm working on, I have alot of information I need to store in xml. Instead of keep on using any of the methods defined above, I created my own wrapper that does the work for me. I'd recommend you to do the same. Put your effort once and use it over and over again. I'm a huge fan of Fluent Interface and therefore my api works accordingly. Here is an example

        List<string> hierarchyList = new List<string>();
        hierarchyList.Add("Book");
        hierarchyList.Add("Product");
        ConfigurationManager manager = new ConfigurationManager();
        manager.FileName = "deleteme.xml";

        expression = new ConfigurationManagerExpression(manager);
        expression.AddNode("HierarchySet");

        // ROOT_NODE_CONSTANT is the root node of document
        string nodePath = manager.ROOT_NODE_CONSTANT + "/HierarchySet";

        foreach (string name in hierarchyList)
        {
            expression.UsingNode(nodePath).AddNode("HierarchyName").AssignValue(name);
        }

        string panelPrefix = "PE";
        string pathWithFileName = "define your path here";
        manager.SaveSettings(pathWithFileName );
Let me know if you need code and I"ll post it on my blog (which I need to do eventually).
Sheraz
A: 

Use XML Typed Templates from MVP.XML.

Alex Angas
+2  A: 

Use the PasteXmlAsLinq sample from Visual Studio 2008. Open C:\Program Files\Microsoft Visual Studio 9.0\Samples\1033\CSharpSamples.zip and extract the LinqSamples\PasteXmlAsLinq files. A Readme file tells you how to set up and use it.

Alex Angas
A: 

Only use the API and have lots of CreateElement, AppendChild, etc. methods:

XmlNode carNode = xmlDocument.CreateElement("Car");
xmlDocument.DocumentElement.AppendChild(carNode);
XmlNode makeNode = xmlDocument.CreateElement("Make");
carNode.AppendChild(makeNode);
...
Alex Angas
A: 

Use a string for each component of the document. Values for the document are inserted by String.Format, then LoadXml converts this into an XmlDocument:

string carString =
  "<Car>" +
  "  <Make>{0}</Make>" +
  "  <Model>{1}</Model>" +
  "</Car>";
XmlDocument carDoc = new XmlDocument();
carDoc.LoadXml(String.Format(carString, make, model));
Alex Angas