我现在正在学习XmlDocument,但我刚刚遇到XDocument,当我试图搜索它们的差异或好处时,我找不到有用的东西,你能告诉我为什么你会使用一个而不是另一个吗?


当前回答

另外,请注意XDocument在Xbox 360和Windows Phone OS 7.0中是受支持的。 如果您以它们为目标,则为XDocument开发或从XmlDocument迁移。

其他回答

正如在其他地方提到的,毫无疑问,与XmlDocument相比,Linq to Xml使Xml文档的创建和更改变得轻而易举,并且XNamespace ns + "elementName"语法在处理名称空间时使阅读变得愉快。

对于xsl和xpath顽固分子来说,值得一提的一点是,在Linq 2 Xml xnode上仍然可以执行任意的xpath 1.0表达式,包括:

using System.Xml.XPath;

然后我们可以通过这些扩展方法使用xpath导航和投影数据:

XPathSelectElement -单个元素 XPathSelectElements -节点集 XPathEvaluate -标量和其他

例如,给定Xml文档:

<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>

我们可以评估:

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)");

到目前为止,没有一个答案提到XmlDocument不提供行信息,而XDocument提供行信息(通过IXmlLineInfo接口),这让我感到惊讶。

在某些情况下,这可能是一个关键的特性(例如,如果您想报告XML中的错误,或者跟踪元素的一般定义位置),在愉快地开始使用XmlDocument实现之前,您最好了解这一点,以免稍后发现必须全部更改。

我相信XDocument进行了更多的对象创建调用。我认为在处理大量XML文档时,XMLDocument会更快。

这种情况发生在管理扫描数据时。许多扫描工具以XML格式输出数据(原因很明显)。如果必须处理大量这样的扫描文件,我认为使用XMLDocument会有更好的性能。

XDocument是从LINQ到XML API, XmlDocument是用于XML的标准dom风格API。如果您非常了解DOM,并且不想学习从LINQ到XML,那么可以使用XmlDocument。如果你对这两个都不熟悉,看看这个页面,比较一下这两个,然后选择一个你更喜欢的外观。

我刚刚开始使用LINQ to XML,我喜欢使用函数结构创建XML文档的方式。真的很好。相比之下,DOM比较笨拙。

如果您使用的是。net 3.0或更低版本,则必须使用XmlDocument,也就是经典的DOM API。同样地,你会发现有其他一些api也会期望这样做。

但是,如果可以选择的话,我强烈建议使用XDocument,也就是LINQ to XML。创建和处理文档要简单得多。例如,它是以下两者之间的区别:

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")));

在LINQ to XML中使用名称空间非常容易,这与我见过的任何其他XML API都不同:

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

LINQ to XML也可以很好地与LINQ一起工作——它的构造模型允许你非常容易地构建带有子元素序列的元素:

// 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
    ));

它更具有声明性,这符合一般的LINQ风格。

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.