我在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"]
但我仍然想知道是否有更简单的方法。
答案 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的内容。