我有这个XML:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<ExtractResponse xmlns="http://tempuri.org/">
<ExtractResult xmlns:a="http://schemas.datacontract.org/2004/07/Sunstein.Services.WebServiceClient.ClientMatter" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ClientMatterNumber>
<a:ClientNumber>00005</a:ClientNumber>
<a:MatterNumber>00003</a:MatterNumber>
</a:ClientMatterNumber>
<a:ClientMatterNumber>
<a:ClientNumber>01234</a:ClientNumber>
<a:MatterNumber>00101</a:MatterNumber>
</a:ClientMatterNumber>
<a:ClientMatterNumber>
<a:ClientNumber>01234</a:ClientNumber>
<a:MatterNumber>01234</a:MatterNumber>
</a:ClientMatterNumber>
</ExtractResult>
</ExtractResponse>
</s:Body>
</s:Envelope>
我正在尝试构建XPath以最终引用其中一个ClientMatterNumber
节点,但在构建它时,我遇到了麻烦。例如,这有效:
/s:Envelope/s:Body
但是这没有结果:
/s:Envelope/s:Body/ExtractResponse
我错过了什么?我已经尝试过许多在线XPath测试人员,包括this,但他们都会导致相同的行为。
答案 0 :(得分:5)
文档中的元素ExtractResponse
具有名称空间uri http://tempuri.org/
。
XPath表达式中任何未加前缀的位置步骤,例如表达式中的ExtractResponse
将没有名称空间uri,因此无法将元素与URI匹配。
要解决此问题,您需要声明命名空间映射(例如x=http://tempuri.org/
),将其传递给XPath引擎并相应地修改表达式(例如/s:Envelope/s:Body/x:ExtractResponse
)。
注意:您提到的在线XPath测试工具是一个很好的工具,但对XML命名空间的支持有限,因此您无法使用该工具成功运行表达式。
答案 1 :(得分:3)
如果出于某种原因,您无法将命名空间绑定到XPath引擎的前缀(如wero在其答案中正确说明),则可以在谓词中使用local-name()
来检查名称:
/s:Envelope/s:Body/*[local-name() = 'ExtractResponse']
您还可以使用namespace-uri()
确保您匹配您想要的确切元素:
/s:Envelope/s:Body/*[local-name()='ExtractResponse' and namespace-uri()='http://tempuri.org/']