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 轴时(其谓词是以反向文档顺序表示的,例如preceding
和preceding-sibling
),情况也是如此。
相比之下,大多数 LINQ to XML 轴按文档顺序返回集合。 但是,其中的两个集合,Ancestors 和 AncestorsAndSelf,会按反向文档顺序返回。 以下表格列出各个轴,并指示每个轴的收集顺序:
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 表达式中,位置谓词对于许多轴以文档顺序表示,而对于反向轴则以反向文档顺序表示。 反向轴为: preceding
、 preceding-sibling
、 ancestor
和 ancestor-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 |
后面 | 没有直接等效项。 |
前面 | 没有直接等效项。 |