592

I am now learning XmlDocument but I've just ran into XDocument and when I try to search the difference or benefits of them I can't find something useful, could you please tell me why you would use one over another ?

nawfal
  • 70,104
  • 56
  • 326
  • 368
Tarik
  • 79,711
  • 83
  • 236
  • 349
  • 17
    I'm wondering why the documentation guys in Microsoft did not put any note or remark in MSDN to clarify their differences or when to use what. – Kamran Bigdely May 21 '15 at 17:43
  • 1
    Some info on msdn: https://msdn.microsoft.com/en-us/library/bb387021.aspx?f=255&MSPPError=-2147217396. And a performance question: http://stackoverflow.com/questions/4383919/performance-xdocument-versus-xmldocument. Personally I have found it easier to work with LINQ to XML. – nawfal Aug 19 '15 at 10:09

7 Answers7

556

If you're using .NET version 3.0 or lower, you have to use XmlDocument aka the classic DOM API. Likewise you'll find there are some other APIs which will expect this.

If you get the choice, however, I would thoroughly recommend using XDocument aka LINQ to XML. It's much simpler to create documents and process them. For example, it's the difference between:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("root");
root.SetAttribute("name", "value");
XmlElement child = doc.CreateElement("child");
child.InnerText = "text node";
root.AppendChild(child);
doc.AppendChild(root);

and

XDocument doc = new XDocument(
    new XElement("root",
                 new XAttribute("name", "value"),
                 new XElement("child", "text node")));

Namespaces are pretty easy to work with in LINQ to XML, unlike any other XML API I've ever seen:

XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc

LINQ to XML also works really well with LINQ - its construction model allows you to build elements with sequences of sub-elements really easily:

// Customers is a List<Customer>
XElement customersElement = new XElement("customers",
    customers.Select(c => new XElement("customer",
        new XAttribute("name", c.Name),
        new XAttribute("lastSeen", c.LastOrder)
        new XElement("address",
            new XAttribute("town", c.Town),
            new XAttribute("firstline", c.Address1),
            // etc
    ));

It's all a lot more declarative, which fits in with the general LINQ style.

Now as Brannon mentioned, these are in-memory APIs rather than streaming ones (although XStreamingElement supports lazy output). XmlReader and XmlWriter are the normal ways of streaming XML in .NET, but you can mix all the APIs to some extent. For example, you can stream a large document but use LINQ to XML by positioning an XmlReader at the start of an element, reading an XElement from it and processing it, then moving on to the next element etc. There are various blog posts about this technique, here's one I found with a quick search.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Could you tell me why they are different ? I mean yeah XDocument looks pretty neat but as for DOM level difference, aren't they both xml, is there any scheme that shows both Microsoft X-DOM and W3C Compliant DOM ? Thanks. – Tarik Oct 09 '09 at 06:36
  • 3
    What do you mean by "scheme" and what do you mean by "shows"? Yes, they both deal with standard XML, but LINQ to XML is just a nicer API for most things. A lot of the technology *behind* LINQ to XML simply wasn't available before .NET 3.5. – Jon Skeet Oct 09 '09 at 06:39
  • I mean whether their document object models are different ? – Tarik Oct 09 '09 at 06:42
  • 6
    Well they're both APIs for XML itself, so in that sense they're not different, no. I suspect both have some limitations (and there's a LINQ to XML one which I know about but can't remember off the top of my head) but in most cases you can just treat them as being the same model with slightly different representations. – Jon Skeet Oct 09 '09 at 07:09
  • @JonSkeet in your last example with the customer list. How would one proceed if foreach customer in the list I want to create a pair of XElement, like so : `1Bob2Frank`. I've tried in the select to create more than one element separating with a comma like so : `.Select(c => new XElement("id", c.id), new XElement("name", c.name));` But apparently thats not the syntax – WizLiz Oct 16 '15 at 08:50
  • @WizLiz: I suggest you ask a new question rather than us trying to deal with it in comments. – Jon Skeet Oct 16 '15 at 15:55
  • At first I thought this would fit this answer, then I decided to ask a new one which has been done and answered. Thanks :) – WizLiz Oct 16 '15 at 16:06
  • This is ancient, but the "much simpler to create documents" (using XDocument) is pretty thin. It is trivial to add your own XmlDocument/XmlElement extension methods to get the Linq-esq functional chaining. For ex: `public static XmlElement AppendElement(this XmlElement parent, string prefix, string name, string ns) { var child = parent.OwnerDocument.CreateElement(prefix, name, ns); parent.AppendChild(child); return child; }` – SensorSmith Oct 28 '15 at 20:07
  • 1
    @SensorSmith: That doesn't cover all the other bonuses though, like automatic flattening of sequences, handling of DateTime etc. You could add extensions methods for all that too, but why reinvent LINQ to XML when you can just use it instead? – Jon Skeet Oct 28 '15 at 22:43
  • Is there any way to use `XPath` notations in conjunction with the`XLinQ`, in my query, if the same deals with `xmlns:*`? – Cylian Apr 07 '16 at 18:03
  • @Cylian: I'm afraid I don't understand your question. I suggest you ask with much more details in a new post. – Jon Skeet Apr 07 '16 at 18:05
67

I am surprised none of the answers so far mentions the fact that XmlDocument provides no line information, while XDocument does (through the IXmlLineInfo interface).

This can be a critical feature in some cases (for example if you want to report errors in an XML, or keep track of where elements are defined in general) and you better be aware of this before you happily start to implement using XmlDocument, to later discover you have to change it all.

Julien Guertault
  • 1,324
  • 1
  • 15
  • 25
  • 1
    And I am surprised nobody noticed that your statement is inversely true. XmlDocument DOES provide the line information while XDocument doesn't. – VVS Dec 29 '17 at 11:46
  • 7
    @VVS: you got me worried for a moment that I had made a terrible typo, but after double checking, I confirm that `XDocument` does provide line information. See [XDocument.Load](https://msdn.microsoft.com/en-us/library/bb538371%28v=vs.110%29.aspx) with `LoadOptions.SetLineInfo` as a second argument. If you know a way to get line information with `XmlDocument` I am curious; back when I wrote this answer I couldn't find any. This other answer seems to confirm: https://stackoverflow.com/a/33622102/253883 – Julien Guertault Dec 31 '17 at 19:18
  • 2
    "and you better be aware of this before you happily start to implement using XmlDocument, to later discover you have to change it all." Guess what I just did :) – Paul Jun 28 '19 at 09:39
44

XmlDocument is great for developers who are familiar with the XML DOM object model. It's been around for a while, and more or less corresponds to a W3C standard. It supports manual navigation as well as XPath node selection.

XDocument powers the LINQ to XML feature in .NET 3.5. It makes heavy use of IEnumerable<> and can be easier to work with in straight C#.

Both document models require you to load the entire document into memory (unlike XmlReader for example).

Irshad
  • 3,071
  • 5
  • 30
  • 51
Brannon
  • 25,687
  • 5
  • 39
  • 44
  • 3
    I think you meant "and can be easier to work with in straight VB.net". Because VB supports direct creation of elements where C# still requires code. – Brain2000 Apr 27 '17 at 15:46
30

As mentioned elsewhere, undoubtedly, Linq to Xml makes creation and alteration of xml documents a breeze in comparison to XmlDocument, and the XNamespace ns + "elementName" syntax makes for pleasurable reading when dealing with namespaces.

One thing worth mentioning for xsl and xpath die hards to note is that it IS possible to still execute arbitrary xpath 1.0 expressions on Linq 2 Xml XNodes by including:

using System.Xml.XPath;

and then we can navigate and project data using xpath via these extension methods:

For instance, given the Xml document:

<xml>
    <foo>
        <baz id="1">10</baz>
        <bar id="2" special="1">baa baa</bar>
        <baz id="3">20</baz>
        <bar id="4" />
        <bar id="5" />
    </foo>
    <foo id="123">Text 1<moo />Text 2
    </foo>
</xml>

We can evaluate:

var node = xele.XPathSelectElement("/xml/foo[@id='123']");
var nodes = xele.XPathSelectElements(
"//moo/ancestor::xml/descendant::baz[@id='1']/following-sibling::bar[not(@special='1')]");
var sum = xele.XPathEvaluate("sum(//foo[not(moo)]/baz)");
StuartLC
  • 104,537
  • 17
  • 209
  • 285
28

XDocument is from the LINQ to XML API, and XmlDocument is the standard DOM-style API for XML. If you know DOM well, and don't want to learn LINQ to XML, go with XmlDocument. If you're new to both, check out this page that compares the two, and pick which one you like the looks of better.

I've just started using LINQ to XML, and I love the way you create an XML document using functional construction. It's really nice. DOM is clunky in comparison.

Irshad
  • 3,071
  • 5
  • 30
  • 51
Daniel Chambers
  • 1,645
  • 16
  • 25
14

Also, note that XDocument is supported in Xbox 360 and Windows Phone OS 7.0. If you target them, develop for XDocument or migrate from XmlDocument.

Nikolai Samteladze
  • 7,699
  • 6
  • 44
  • 70
w0land
  • 141
  • 1
  • 4
-10

I believe that XDocument makes a lot more object creation calls. I suspect that for when you're handling a lot of XML documents, XMLDocument will be faster.

One place this happens is in managing scan data. Many scan tools output their data in XML (for obvious reasons). If you have to process a lot of these scan files, I think you'll have better performance with XMLDocument.

Charles Menguy
  • 40,830
  • 17
  • 95
  • 117
Brian
  • 13
  • 12
    I think you should back your comment up with figures next time, as I believe you may be wrong. See http://blogs.msdn.com/b/codejunkie/archive/2008/10/08/xmldocument-vs-xelement-performance.aspx – mike Jun 18 '12 at 06:58