【问题标题】:XPath Equivalent of "match any"“匹配任何”的 XPath 等效项
【发布时间】:2014-05-08 18:19:17
【问题描述】:

我在 SOAP 消息上使用了以下 XPath:

//*[contains('RedID,GreenID,BlueID',local-name())]

使用 XPathNavigator 可以完美运行,除非 SOAP 主体包含如下内容:

<s:Body>
<RunStuff xmlns="http://serve.com/2013/11">
    <arg>5</arg>
    <data xmlns:b="http://schemas.datacontract.org/2004/07/Injection.Test" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <b:ID>5</b:ID>
        <b:BlueID>600d2517-7126-4fcf-8155-c4a50ab3cc10</b:BlueID>
        <b:account>0</b:account>
    </data>
</RunStuff>
</s:Body>

XPath 将匹配 ID 元素,而不是我试图捕获的 BlueID。我可以简单地收集所有结果并过滤掉错误的匹配项,但我想知道是否有更聪明的 XPath 语句不会意外匹配 ID 字段,或者意外匹配名为 Blue 的字段,等等。

MSDN 文档说XPathNavigator supports XPath 1.0 and 2.0,但是当我尝试这个时......

//*[local-name()=('RedID','BludID')]

...我收到一个错误的令牌错误。我从this link 得到了那个语法。于是我就试了一下……

//*[exists(index-of(('RedID','BlueID'), 'RedID) )]

这也给了我一个错误的令牌错误。我还尝试了另一个变体,它给了我一个错误,说我必须加载 XsltContext。这个错误让我找到了this solution。用户“ertan”的回答涉及编写我自己的 C# 函数,这比我预期的要复杂。我正在寻找更简单的东西——XPath“按原样”直接支持的东西。

如果必须的话,我将求助于构建一堆or 语句...

//*[local-name()="RedID" OR local-name()="BludID"]

但我还是想知道有没有更简单的方法。

【问题讨论】:

    标签: xml xpath


    【解决方案1】:

    您在这里几乎无法使用contains(),因为您使用的是字符串值列表而不是节点列表,但您可以这样做以防止任何部分匹配:

    //*[contains('|RedID|GreenID|BlueID|', concat('|', local-name(), '|'))]
    

    MSDN 文档没有说XPathNavigator 支持XPath 2.0 表达式。它说的是:

    System.Xml.XPath 命名空间中的 XPathNavigator 类是一个抽象类,它将用于导航和编辑 XML 信息项的光标模型定义为 XQuery 1.0 和 XPath 2.0 数据模型的实例

    我很确定 .NET 中没有内置任何东西支持 XPath 2.0。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多