XDocument或XmlDocument

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

216955 次浏览

如果你使用的是。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);

而且

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风格。

现在,正如Brannon提到的,这些是内存中的api,而不是流api(尽管XStreamingElement支持惰性输出)。XmlReaderXmlWriter是在. net中流式传输XML的正常方式,但在某种程度上可以混合使用所有api。例如,你可以流化一个大的文档,但是使用LINQ到XML,方法是在元素的开头定位XmlReader,从中读取XElement并处理它,然后转移到下一个元素等等。关于这项技术有很多博客文章,这是我快速搜索找到的

XDocument是从LINQ到XML的API, XmlDocument是用于XML的标准dom风格API。如果你很了解DOM,但不想学习从LINQ到XML,那就选择XmlDocument。如果你对这两个都不熟悉,请查看比较这两个的这个页面,并选择你更喜欢哪个外观。

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

XmlDocument非常适合熟悉XML DOM对象模型的开发人员。它已经存在了一段时间,或多或少地与W3C标准相对应。它支持手动导航和XPath节点选择。

XDocument支持。net 3.5中的LINQ to XML特性。它大量使用IEnumerable<>,并且更容易直接使用c#。

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

同时,请注意XDocument在Xbox 360和Windows Phone OS 7.0中是支持的。 如果你的目标是他们,开发XDocument或从XmlDocument迁移

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

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

到目前为止,我很惊讶没有一个答案提到XmlDocument不提供任何行信息,而# EYZ1确实(通过IXmlLineInfo接口)。

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

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

值得一提的是,xslxpath die fans要注意的是,它仍然可以在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)");