在 XPath 中选择特定元素
Choosing specific element in XPath
我得到了 2 个同名元素 "reason"。当我使用 //*:reason/text()
它给了我两个元素,但我需要第一个。 (不是 "details" 里面的那个)。请帮助..
<xml xmlns:gob="http://osb.yes.co.il/GoblinAudit">
<fault>
<ctx:fault xmlns:ctx="http://www.bea.com/wli/sb/context">
<ctx:errorCode>BEA-382500</ctx:errorCode>
<ctx:reason>OSB Service Callout action received SOAP Fault response</ctx:reason>
<ctx:details>
<ns0:ReceivedFaultDetail xmlns:ns0="http://www.bea.com/wli/sb/stages/transform/config">
<ns0:faultcode xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">soapenv:Server</ns0:faultcode>
<ns0:faultstring>BEA-380001: Internal Server Error</ns0:faultstring>
<ns0:detail>
<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
<con:errorCode>BEA-380001</con:errorCode>
<con:reason>Internal Server Error</con:reason>
<con:location>
<con:node>RouteTo_FinancialControllerBS</con:node>
<con:path>response-pipeline</con:path>
</con:location>
</con:fault>
</ns0:detail>
</ns0:ReceivedFaultDetail>
</ctx:details>
<ctx:location>
<ctx:node>PipelinePairNode2</ctx:node>
<ctx:pipeline>PipelinePairNode2_request</ctx:pipeline>
<ctx:stage>set maintain offer</ctx:stage>
<ctx:path>request-pipeline</ctx:path>
</ctx:location>
</ctx:fault>
</fault>
</xml>
您正在使用 //
限定符,它将下降到任何子树并找到 reason
的所有出现。您可以尝试更具体的子路径:
//fault/*:fault/*:reason/text()
这只会匹配外部 reason
但不会匹配内部 reason.
。
"...but i need the first one"
您可以使用位置索引来获取第一个匹配的 reason
元素:
(//*:reason)[1]/text()
" (not the one inside "details")"
以上可以表示为寻找reason
没有祖先的元素details
:
//*:reason[not(ancestor::*:details)]/text()
对于大型 XML 文档,使用更具体的路径,即避免在开头使用 //
,会导致更高效的 XPath :
/xml/fault/*:fault/*:reason/text()
但对于小XML来说,这只是个人喜好问题,因为改进可能可以忽略不计。
我得到了 2 个同名元素 "reason"。当我使用 //*:reason/text()
它给了我两个元素,但我需要第一个。 (不是 "details" 里面的那个)。请帮助..
<xml xmlns:gob="http://osb.yes.co.il/GoblinAudit">
<fault>
<ctx:fault xmlns:ctx="http://www.bea.com/wli/sb/context">
<ctx:errorCode>BEA-382500</ctx:errorCode>
<ctx:reason>OSB Service Callout action received SOAP Fault response</ctx:reason>
<ctx:details>
<ns0:ReceivedFaultDetail xmlns:ns0="http://www.bea.com/wli/sb/stages/transform/config">
<ns0:faultcode xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">soapenv:Server</ns0:faultcode>
<ns0:faultstring>BEA-380001: Internal Server Error</ns0:faultstring>
<ns0:detail>
<con:fault xmlns:con="http://www.bea.com/wli/sb/context">
<con:errorCode>BEA-380001</con:errorCode>
<con:reason>Internal Server Error</con:reason>
<con:location>
<con:node>RouteTo_FinancialControllerBS</con:node>
<con:path>response-pipeline</con:path>
</con:location>
</con:fault>
</ns0:detail>
</ns0:ReceivedFaultDetail>
</ctx:details>
<ctx:location>
<ctx:node>PipelinePairNode2</ctx:node>
<ctx:pipeline>PipelinePairNode2_request</ctx:pipeline>
<ctx:stage>set maintain offer</ctx:stage>
<ctx:path>request-pipeline</ctx:path>
</ctx:location>
</ctx:fault>
</fault>
</xml>
您正在使用 //
限定符,它将下降到任何子树并找到 reason
的所有出现。您可以尝试更具体的子路径:
//fault/*:fault/*:reason/text()
这只会匹配外部 reason
但不会匹配内部 reason.
。
"...but i need the first one"
您可以使用位置索引来获取第一个匹配的 reason
元素:
(//*:reason)[1]/text()
" (not the one inside "details")"
以上可以表示为寻找reason
没有祖先的元素details
:
//*:reason[not(ancestor::*:details)]/text()
对于大型 XML 文档,使用更具体的路径,即避免在开头使用 //
,会导致更高效的 XPath :
/xml/fault/*:fault/*:reason/text()
但对于小XML来说,这只是个人喜好问题,因为改进可能可以忽略不计。