XPath相当于"匹配任何"

时间:2014-05-08 18:19:17

标签: xml xpath

我在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。用户&#34; ertan&#34;编写我自己的C#函数,这比我想要的更多。我正在寻找更简单的东西 - XPath直接支持的东西&#34;&#34;。

如果我必须......我将采用构建一堆or语句。

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

但我仍然想知道是否有更简单的方法。

1 个答案:

答案 0 :(得分:3)

您在这里使用contains()时非常困难,因为您正在处理字符串值列表而不是节点列表,但您可以这样做以防止任何部分匹配:

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

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

  
    

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

我非常确定.NET中没有内置任何支持XPath 2.0的内容。