XDocument或XmlDocument

595

我现在正在学习XmlDocument,但是我刚接触到XDocument,当我尝试搜索它们之间的差异或优势时,我找不到有用的信息,请问您可以告诉我为什么会使用其中一个而不是另一个吗?


17
我想知道为什么微软的文档团队在MSDN中没有加入任何注释或备注来澄清它们之间的差异或何时使用哪个。 - Kamran Bigdely
7个回答

557
如果你正在使用 .NET 版本 3.0 或更低版本,则必须使用传统的 DOM API,即 XmlDocument。同样,你会发现其他一些 API 也需要使用它。
然而,如果可以选择,我强烈建议使用 LINQ to XML,即 XDocument。它更容易创建和处理文档。例如,这是以下两者之间的区别:
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);

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

这些API更加声明性,符合一般LINQ的风格。

现在,正如Brannon所提到的,这些是内存中的API,而不是流式API(尽管支持惰性输出)。在.NET中,XmlReaderXmlWriter是流式处理XML的常规方式,但是您可以在一定程度上混合使用所有API。例如,您可以流式处理大型文档,但使用LINQ to XML通过将XmlReader定位在元素的开头,从中读取一个并对其进行处理,然后继续移动到下一个元素等。有关此技术的各种博客文章,在这里我找到了一篇快速搜索的文章


3
“Scheme”和“shows”是什么意思?是的,它们都涉及标准XML,但LINQ to XML对于大多数事情来说只是一个更好的API。在.NET 3.5之前,许多LINQ to XML背后的技术根本不可用。 - Jon Skeet
6
它们都是针对XML本身的API,所以从这个意义上说它们并没有不同。我怀疑它们都有一些限制(还有一个LINQ to XML,但我无法立即记起),但在大多数情况下,你可以将它们视为相同的模型,只是呈现略有不同。 - Jon Skeet
@JonSkeet 在你最后一个客户列表的例子中,如果我想要在列表中为每个客户创建一对XElement,该怎么办?就像这样:<customers><id>1</id><name>Bob</name><id>2</id><name>Frank</name></customers>。我尝试在选择器中使用逗号分隔符创建多个元素,例如:.Select(c => new XElement("id", c.id), new XElement("name", c.name)); 但显然这不是正确的语法。 - WizLiz
@WizLiz:我建议您提出一个新问题,而不是我们试图通过评论来处理它。 - Jon Skeet
1
@SensorSmith:但这并没有涵盖所有其他的奖励,比如自动展平序列、处理 DateTime 等。你也可以为所有这些添加扩展方法,但为什么要重新发明 LINQ to XML 呢?直接使用它不就好了吗? - Jon Skeet
显示剩余6条评论

67
我很惊讶目前为止所有的回答都没有提到一个事实,那就是XmlDocument不提供行信息,而XDocument提供了(通过IXmlLineInfo接口)。
在某些情况下,这可能是一个关键特性(例如,如果您想报告 XML 中的错误或跟踪元素定义的位置),因此在愉快地开始使用XmlDocument来实现后,最好意识到这一点,以免以后要改变所有内容。

1
我很惊讶,没有人注意到你的陈述是相反的。XmlDocument提供了行信息,而XDocument则没有。 - VVS
7
@VVS:你让我担心了一会儿,让我以为我犯了一个可怕的错别字,但是经过仔细检查,我确认XDocument确实提供了行信息。请参阅XDocument.Load,第二个参数使用LoadOptions.SetLineInfo。如果您知道如何使用XmlDocument获取行信息,我很好奇;当我写这个答案时,我找不到任何方法。另一个答案似乎证实了这一点:https://dev59.com/FlbTa4cB1Zd3GeqP7x81#33622102。 - Julien Guertault
2
在你开心地开始使用XmlDocument实现之前,最好意识到这一点,以免后来发现你不得不全部更改。 你猜我刚刚做了什么 :) - Paul

45

XmlDocument适用于熟悉XML DOM对象模型的开发人员。它已经存在一段时间,并且更多或少对应于W3C标准。它支持手动导航以及XPath节点选择。

XDocument为.NET 3.5中的LINQ to XML功能提供支持。它广泛使用IEnumerable<>,在纯C#中使用更加容易。

这两种文档模型都要求您将整个文档加载到内存中(与XmlReader不同)。


3
我想你的意思是“在 VB.net 中直接创建元素会更容易”,因为 VB 支持直接创建元素,而 C# 仍需要代码。 - Brain2000

30

如前所述,毫无疑问,与XmlDocument相比,Linq to Xml使得创建和修改xml文档变得轻而易举,而XNamespace ns + "elementName"的语法在处理命名空间时确实让人愉悦。

值得一提的是,对于xslxpath的忠实拥趸们需要注意的一点是,仍然有可能在Linq 2 Xml XNodes上执行任意的xpath 1.0表达式,方法是加入:

using System.Xml.XPath;

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

例如,给定 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)");

28

XDocument来自于LINQ to XML API,而XmlDocument则是XML标准的DOM风格API。如果您了解DOM,并且不想学习LINQ到XML,则应该选择XmlDocument。如果您对两者都不熟悉,请查看此页面进行比较,并选择您更喜欢的那个。

我刚刚开始使用LINQ to XML,并且我很喜欢使用函数式构造创建XML文档的方式。相比之下,DOM就显得笨重了。


14

另外,需要注意的是XDocument支持Xbox 360和Windows Phone OS 7.0。 如果你的目标平台是它们之一,就要使用XDocument进行开发或从XmlDocument进行迁移。


-10

我认为XDocument会产生更多的对象创建调用。如果你要处理大量的XML文档,我怀疑XMLDocument会更快。

这种情况发生在管理扫描数据时。许多扫描工具以XML格式输出其数据(出于显而易见的原因)。如果你需要处理大量这些扫描文件,我认为使用XMLDocument可以获得更好的性能。


12
下次,我觉得你应该用数字来支持你的评论,因为我认为你可能是错的。请参阅http://blogs.msdn.com/b/codejunkie/archive/2008/10/08/xmldocument-vs-xelement-performance.aspx。 - mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接