【问题标题】:.Net standard library that supports XPath 3.1支持 XPath 3.1 的 .Net 标准库
【发布时间】:2019-05-22 09:04:03
【问题描述】:

我正在维护我工作的公司的一个遗留工具,用 C# 编写,并将其转换为 .Net 标准 2.0。它使用Saxon-HE 处理器来处理一些XPath 并替换文件中的一些配置。 它在.NET 上的NuGet package 具有不允许在所有.Net 标准2.0 兼容平台(在我的情况下是.Net Framework 和.Net 核心)上执行的依赖项,所以我需要用另一种工具替换它,更好如果是标准的 .Net XPath 库。

问题是该工具使用了一些 XPaths 来执行复杂的操作,例如连接字符串和选择一个数组项,我不知道它是 Saxon 特定的语法还是标准。

了解这一点很重要,因为如果 XPath 符合某些 XPath 标准,我可以找到另一种方法来处理相同的 XPath。

这里有一些例子:

第一:

for $row in /Item/SubItem[*]/SubSubItem return(concat($row, \"/ConcatValue\"))

第二:

/Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(), '')[1]

您对这种 XPath 语法有所了解吗?

谢谢

【问题讨论】:

  • 请从您使用的标签的 SO 页面stackoverflow.com/tags/xpath-3.1/info 方便地为您链接查看相关的 XPath 规范。而且我不知道谁会考虑在 XPath 中使用 concat 一个“复杂”操作。
  • github.com/StefH/XPath2.Net 声称它以与 .NET Standard 2.0 兼容的方式支持 XPath 2.0。
  • 当你说“它的 NuGet 包不符合 .Net 标准”时,我的想法是否正确,你的意思是 .NET 上的 Saxon 具有依赖关系,这意味着它不会在所有兼容的平台上运行,具体来说,它不会在 .NET Core 上运行”?因为按照您的措辞,听起来 NuGet 包有问题,这很容易解决。
  • @MichaelKay 是的,我需要这个应用程序在 .Net 框架和 .Net 核心环境中运行,所以使用的所有依赖项都必须符合 .Net 标准 2.0 才能执行“一切”。很抱歉措辞错误,我现在正在修复它

标签: xpath xquery saxon xquery-3.1 xpath-3.1


【解决方案1】:

您作为示例给出的 XPath 表达式需要 XPath 2.0 处理器,但它们并不特定于 Saxon。

表达式

for $row in /Item/SubItem[*]/SubSubItem return(concat($row, \"/ConcatValue\"))

是一个ForExpression,它是XPath 2.0特有的,不容易转换成XPath 1.0,因为它的结果是一个字符串序列,而XPath 1.0中没有这种数据类型。

表达式

/Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(), '')[1]

特定于 XPath 2.0,因为它在“/”运算符的 RHS 上使用带括号的表达式;再次,因为它返回一个字符串序列。

恐怕我无法告诉您是否存在在 .NET Core 上运行的 XPath 2.0 库,我认为这是您的要求。 Saxon 无法在 .NET Core 上运行,因为它依赖于 IKVM,IKVM 不支持该平台,而且(我认为)不能轻易适应。

请注意,XPath 2.0 是 XQuery 1.0 的子集,因此您可以将搜索扩展到 XQuery 1.0 处理器以及 XPath 2.0 处理器。

【讨论】:

    【解决方案2】:

    感谢this 评论,我能够测试XPath2.Net,现在一切正常。我只需要更改一种类型的 XPath 定义

    这个:

    /Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(), '')[1]
    

    变化

    /Item/SubItem[*]/SubSubItem/(add[@key=\"TheKey\"]/@value/string(.), '')[1]
    

    请注意string() 函数的附加点参数。 这很奇怪,因为它不需要点;事实上,根据standard

    在函数的零参数版本中,$arg 默认为 上下文项。也就是说,调用 fn:string() 等价于调用 fn:string(.)

    但 XPath2 报此错误

    {"The function 'string'/0 was not found in namespace 'http://www.w3.org/2003/11/xpath-functions'"}
    

    更新:

    将 XPath2.Net 库更新到 1.0.8 版后,string() 语法可以正常工作。

    【讨论】:

    • 它给出的命名空间 URI 为 http://www.w3.org/2003/11/xpath-functions 也有点令人担忧,因为这不是最终版本规范中使用的命名空间。
    • 至于零字符串参数调用,我已经在github.com/StefH/XPath2.Net/issues/23 中提出了一个可能解决此问题的问题,所以也许你会看到一个新版本解决了这个问题。
    • 我可以确认,在 XPath2 库 (1.0.8) 的最新更新中,string() 语法按预期工作。我相应地更新了答案
    猜你喜欢
    • 2021-11-06
    • 2019-02-06
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多