我现在正在学习 XmlDocument
,但我刚刚遇到 XDocument
,当我尝试搜索它们的区别或好处时,我找不到有用的东西,你能告诉我为什么你会使用一个而不是另一个吗?
如果您使用 .NET 3.0 或更低版本,您必须使用 XmlDocument
,即经典 DOM API。同样,您会发现还有一些其他 API 会期望这一点。
但是,如果您可以选择,我会彻底推荐使用 XDocument
aka 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")));
与我见过的任何其他 XML API 不同,命名空间在 LINQ to XML 中非常容易使用:
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
支持延迟输出)。 XmlReader
和 XmlWriter
是在 .NET 中流式传输 XML 的常规方式,但您可以在一定程度上混合使用所有 API。例如,您可以流式传输大型文档,但使用 LINQ to XML,方法是将 XmlReader
放置在元素的开头,从中读取 XElement
并对其进行处理,然后移动到下一个元素等。有多种有关此技术的博文,here's one I found with a quick search。
令我惊讶的是,到目前为止,没有一个答案提到 XmlDocument
不提供线路信息,而 XDocument
提供(通过 IXmlLineInfo
界面)这一事实。
在某些情况下,这可能是一项关键功能(例如,如果您想报告 XML 中的错误,或跟踪一般定义元素的位置),您最好在愉快地开始使用 XmlDocument
实现之前了解这一点,后来发现你必须改变这一切。
XDocument
确实提供了线路信息。请参阅将 LoadOptions.SetLineInfo
作为第二个参数的 XDocument.Load。如果您知道使用 XmlDocument
获取线路信息的方法,我很好奇;当我写这个答案时,我找不到任何答案。这个其他答案似乎证实了:stackoverflow.com/a/33622102/253883
XmlDocument
非常适合熟悉 XML DOM 对象模型的开发人员。它已经存在了一段时间,或多或少符合 W3C 标准。它支持手动导航以及XPath
节点选择。
XDocument
支持 .NET 3.5 中的 LINQ to XML 功能。它大量使用 IEnumerable<>
并且可以更容易地在直接 C# 中使用。
两种文档模型都要求您将整个文档加载到内存中(例如,与 XmlReader
不同)。
正如在别处提到的,毫无疑问,与 XmlDocument
相比,Linq to Xml 使 xml 文档的创建和更改变得轻而易举,并且 XNamespace ns + "elementName"
语法在处理名称空间时使阅读愉快。
对于 xsl
和 xpath
来说,值得一提的是,仍然可以在 Linq 2 Xml XNodes
上执行任意 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)");
XDocument
来自 LINQ to XML API,XmlDocument
是用于 XML 的标准 DOM 样式 API。如果您非常了解 DOM,并且不想学习 LINQ to XML,请使用 XmlDocument
。如果您对两者都不熟悉,请查看对两者进行比较的 this page,然后选择您更喜欢哪个外观。
我刚刚开始使用 LINQ to XML,我喜欢您使用函数式构造创建 XML 文档的方式。这太好了。相比之下,DOM 显得笨拙。
另请注意,Xbox 360 和 Windows Phone OS 7.0 支持 XDocument
。如果您以他们为目标,请为 XDocument
开发或从 XmlDocument
迁移。
我相信 XDocument
会进行更多的对象创建调用。我怀疑当您处理大量 XML 文档时,XMLDocument
会更快。
发生这种情况的一个地方是管理扫描数据。许多扫描工具以 XML 格式输出数据(原因很明显)。如果您必须处理大量此类扫描文件,我认为使用 XMLDocument
会有更好的性能。
不定期副业成功案例分享