【问题标题】:How to combine two XPath queries in C#如何在 C# 中组合两个 XPath 查询
【发布时间】:2018-08-14 01:00:46
【问题描述】:

我正在尝试通过 XPath 评估检查 XML 文档中的两条规则。

规则是:

  • /root/path1/text()='TABLE1'
  • /root/path2/text()='TABLE2'

我的代码如下:

XPathDocument document = new XPathDocument(myDocument);
XPathNavigator navigator = document.CreateNavigator();
XmlNamespaceManager xpathNsMgr = new XmlNamespaceManager(navigator.NameTable);    
xpathNsMgr.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
var result = (bool)navigator.Evaluate("((/root/path1/text()='TABLE1') and (/root/path2/text()='TABLE2'))", xpathNsMgr);

如果我通过评估自己的 XPath 检查两个 XPath,那么一切正常。但是如果我检查它们的组合,如上面的代码所示,我会收到以下错误:

xsltcontext is needed for this query because of an unknown function

为什么不能将 XPath 结合起来并一起评估它们?自 XPath 1.0 以来,我认为“and”、“or”等都是有效的运算符...

【问题讨论】:

  • 我认为和或用于评估每个element的属性? /root 可能需要在外括号之外。
  • @lloyd 这个 XPath 1.0 是特定的吗?因为上面显示的表达式完美地工作在:freeformatter.com/xpath-tester.html#ad-output
  • 您确定您收到发布的 XPath 表达式的错误吗?我在那里看不到任何未知的功能。您对 Tomalak 的回答的评论显示了函数 exists 的使用,该函数确实未在 XPath 1 中定义。
  • Oh...exists() 确实是 XPath 版本,但是 XPath 2.0...w3schools.com/xml/xsl_functions.asp 所以,我必须搜索另一个库来评估这些表达式,因为它们是通过外部系统/合作伙伴。

标签: c# .net xslt xpath


【解决方案1】:

.NET XPathNavigator 仅支持 XPath 1.0。

您可以通过将条件转换为谓词(方括号)来轻松地为您的检查建模,并查看生成的节点集是否为空。

var result = navigator.Evaluate("/*[path1 = 'TABLE1' and path2 = 'TABLE2']", xpathNsMgr);

这里/* 选择文档元素。如果文档元素的实际名称很重要,请改写 /root

【讨论】:

  • 好的,这适用于给定的示例。但是如果我想合并 (/root/path1/text()='TABLE1') and (exists(/root/path3)) 怎么办?我想我会一一评估它们,然后再进行逻辑检查/组合......
  • exists()?没有这样的功能。选择一个节点会检查它的存在。 /*[path1 = 'TABLE1' and path3].
【解决方案2】:

正如@Tomalak 和@Martin Honnen 所述,XPath 1.0 不完全支持我的条件。像 exists() 这样的函数是 XPath 2.0 的一部分。

由于 .NET 4.5(我必须使用)不支持 XPath 2.0,我使用以下 Nuget 包来解决我的问题:https://www.nuget.org/packages/XPath2/

只需替换

navigator.Evaluate(...

navigator.XPath2Evaluate(...

并且可以计算表达式。

【讨论】:

  • 我怀疑微软的System.Xml.XPath,无论是在任何.NET框架版本中还是作为.NET Core使用的NuGet包,确实支持任何XPath 2函数或表达式,它只是类型系统以及设计为可与 XQuery 1 或 XPath 2 一起使用的 API,但从未进一步实施,或者至少没有进一步发布。因此,Microsoft 为您提供了 XPathNavigator 和 XPathItem 构建 XPath 2 或 XQuery 1 的基础,但如果您想使用这些语言的函数或表达式,则必须求助于第三方实现。
  • @MartinHonnen 我编辑了我的答案。 (最后一句。)这些更改是否反映了您在评论中添加的内容?
  • 不,我认为微软的实现中不支持 XPath 2.0 语法,如序列表达式、for .. in 等。关于“System.Xml.XPath 命名空间包含定义用于导航和编辑 XML 信息项的游标模型的类作为 XQuery 1.0 和 XPath 2.0 数据模型的实例”的声明在 System.Xml.XPath 自 .NET 2.0 的文档中我认为,这就是让微软在那里记录该命名空间的体系结构的原因。放弃了对更多内容的任何支持,转而支持 LINQ to XML。
猜你喜欢
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
相关资源
最近更新 更多