我希望得到以下xml的元素名称。 我的请求中的问题是我想获得Payload元素。为此,我使用了这个表达式
name(//env:Payload)
所以我得到了这个结果环境:有效载荷
<env:requeset xmlns:env="http://eai.ssss.xxx/Envelope" xmlns:ggg="http://fai.dgn.sss/ggg">
<env:clientbody>
<env:Payload>
<ggg:Service>
<ggg:Request>
<a>name</a>
<b>age</b>
<c>address</c>
</ggg:Request>
</ggg:Service>
</env:Payload>
</env:clientbody>
</env:requeset>
但有时我的客户端发送的请求包含不同的元素,有时也没有命名空间。那么我如何得到以下要求呢
<requeset xmlns:="http://eai.ssss.xxx/Envelope" xmlns:ggg="http://fai.dgn.sss/ggg">
<clientbody>
<Payload>
<ggg:Service>
<ggg:Request>
<a>name</a>
<b>age</b>
<c>address</c>
</ggg:Request>
</ggg:Service>
</Payload>
</clientbody>
</requeset>
对于上面的请求,我使用相同的表达式,因此它给出了错误,所以如何在2种情况下获得Payload元素或任何情况。 我试过这个,但它不起作用
name(//( local-name()='Payload'))
给予ERROR - Failed to evaluate XPath expression: A location step was expected following the '/' or '//' token.
所以请指导获取没有命名空间和不同命名空间的元素我也尝试使用Contains表达式,但我无法得到它。
答案 0 :(得分:2)
如错误消息所示,您编写的语法不正确。如果要比较每个元素的本地名称,可以这样做:
//*(local-name() = 'Payload')
但是等等,有更好的选择来实现这一目标。你在这里做的基本上是忽略命名空间。您还可以使用通配符名称空间运算符*
以更清晰的语法实现此目的。它就像
//*:Payload
如果您仍想要尊重命名空间,还可以使用union运算符|
合并两个结果。这样,您可以获得带有env名称空间且没有任何名称空间的Payload元素:
//env:Payload | //Payload
当然,在所有这些情况下,您都可以使用name()
来获取元素名称。
答案 1 :(得分:2)
您误解了数据和问题;因此,您提出的问题与您的情况无关。
您没有任何具有不同命名空间的元素。您显示的两个请求都包含扩展名为{http://eai.ssss.xxx/Envelope} Payload的元素;它们的区别仅在于为该命名空间使用不同的前缀(env
与没有前缀)。同样的查询应该适用于两者;一个简单的演示是:
declare namespace e = "http://eai.ssss.xxx/Envelope";
let $testdata := <data>
<env:requeset xmlns:env="http://eai.ssss.xxx/Envelope"
xmlns:ggg="http://fai.dgn.sss/ggg">
<env:clientbody>
<env:Payload>
...
</env:Payload>
</env:clientbody>
</env:requeset>
<requeset xmlns="http://eai.ssss.xxx/Envelope"
xmlns:ggg="http://fai.dgn.sss/ggg">
<clientbody>
<Payload>
...
</Payload>
</clientbody>
</requeset>
</data>
return $testdata//e:Payload
如果您尝试这样做,您会看到它返回两个元素,而不仅仅是一个元素。
如果第二个示例输入遇到问题,可能是因为字符串xmlns:
不是命名空间声明的合法名称。将xmlns:="http://eai.ssss.xxx/Envelope"
更改为xmlns="http://eai.ssss.xxx/Envelope"
。