XPath 和 LINQ to XML 的比较

XPath 和 LINQ to XML 在某些方面相似。 这两者都可用于查询 XML 树,返回元素集合、属性集合、节点集合或元素或属性的值等结果。 但是,这两个选项之间存在显著差异。

XPath 与 LINQ to XML 之间的差异

XPath 不允许投影新类型。 它只能从树中返回节点集合,而 LINQ to XML 可以在新形状中执行查询和投影对象图或 XML 树。 LINQ to XML 查询能够实现比 XPath 表达式更多的功能。

XPath 表达式在字符串中处于隔离状态。 C# 编译器在编译时无法帮助分析 XPath 表达式。 相比之下,LINQ to XML 查询由 C# 编译器分析和编译。 编译器可以捕获许多查询错误。

XPath 结果不是强类型。 在很多情况下,评估 XPath 表达式的结果是一个对象,由开发人员确定适当的类型并根据需要转换结果。 相比之下,LINQ to XML 查询生成的投影是强类型。

结果排序

XPath 1.0 建议指出,作为计算 XPath 表达式结果的集合未排序。

但是,在循环访问 LINQ to XML XPath 轴方法返回的集合时,集合中的节点按文档顺序返回。 即使在访问这些 XPath 轴时(其谓词是以反向文档顺序表示的,例如precedingpreceding-sibling),情况也是如此。

相比之下,大多数 LINQ to XML 轴按文档顺序返回集合。 但是,其中的两个集合,AncestorsAncestorsAndSelf,会按反向文档顺序返回。 以下表格列出各个轴,并指示每个轴的收集顺序:

LINQ to XML 轴 订购
XContainer.DescendantNodes 文档顺序
XContainer.Descendants 文档顺序
XContainer.Elements 文档顺序
XContainer.Nodes 文档顺序
XContainer.NodesAfterSelf 文档顺序
XContainer.NodesBeforeSelf 文档顺序
XElement.AncestorsAndSelf 将文档顺序逆转
XElement.Attributes (XElement 的属性) 文档顺序
XElement.DescendantNodesAndSelf 文档顺序
XElement.DescendantsAndSelf 文档顺序
XNode.Ancestors 将文档顺序逆转
XNode.ElementsAfterSelf 文档顺序
XNode.ElementsBeforeSelf 文档顺序
XNode.NodesAfterSelf 文档顺序
XNode.NodesBeforeSelf 文档顺序

位置谓词

在 XPath 表达式中,位置谓词对于许多轴以文档顺序表示,而对于反向轴则以反向文档顺序表示。 反向轴为: precedingpreceding-siblingancestorancestor-or-self。 例如,XPath 表达式 preceding-sibling::*[1] 返回紧邻同级。 即使最终结果集按文档顺序显示,也是如此。

相比之下,LINQ to XML 中的所有位置谓词始终以轴顺序表示。 例如, anElement.ElementsBeforeSelf().ElementAt(0) 返回查询元素的父元素的第一个子元素,而不是前一个同级元素。 另一个示例: anElement.Ancestors().ElementAt(0) 返回父元素。

如果要在 LINQ to XML 中找到紧邻的元素,请编写以下表达式:

ElementsBeforeSelf().Last()
ElementsBeforeSelf().Last()

性能差异

使用 LINQ to XML 中的 XPath 功能的 XPath 查询速度将比 LINQ to XML 查询慢。

撰写方式的比较

LINQ to XML 查询的构成类似于 XPath 表达式的构成,但语法大不相同。

例如,如果在一个变量中有一个名为customers的元素,并且您想在所有名为CompanyName的子元素下查找一个名为Customer的孙元素,请编写以下 XPath 表达式:

customers.XPathSelectElements("./Customer/CompanyName")
customers.XPathSelectElements("./Customer/CompanyName")

等效的 LINQ to XML 查询为:

customers.Elements("Customer").Elements("CompanyName")
customers.Elements("Customer").Elements("CompanyName")

每个 XPath 轴都有相似的对应关系。

XPath 轴 LINQ to XML 轴
子级(默认轴) XContainer.Elements
父级 (..) XObject.Parent
属性轴 (@) XElement.Attribute



XElement.Attributes
祖先轴 XNode.Ancestors
上级或自身轴 XElement.AncestorsAndSelf
后代轴 (//) XContainer.Descendants



XContainer.DescendantNodes
后代或自身 XElement.DescendantsAndSelf



XElement.DescendantNodesAndSelf
后面同级 XNode.ElementsAfterSelf



XNode.NodesAfterSelf
前面同级 XNode.ElementsBeforeSelf



XNode.NodesBeforeSelf
后面 没有直接等效项。
前面 没有直接等效项。