如何合并两个XPath表达式获取指定XML元素值?
合并XPath表达式以获取指定元素
给定XML片段
<a:Foo> <a:Value1>42</a:Value1> <a:Value2>bil jac</a:Value2> <a:Bar>corner-bar-and-grill</a:ClientKey> <!-- 注意:此处标签不匹配,<a:Bar>对应了</a:ClientKey>,建议修正为</a:Bar> --> <a:MyArray> <a:MyArrayElement> <a:ValueA>string 1</a:ValueA> <a:ValueB>string 2</a:ValueB> </a:MyArrayElement> </a:MyArray> </a:Foo>
<a:Foo>位于<s:Envelope><s:Body><a:Array1>路径下,需要一个XPath表达式同时获取符合条件的<a:Foo>中的<a:Value1>、<a:Value2>和所有<a:ValueA>元素。
现有表达式
- 获取
Value1和Value2:
/s:Envelope/s:Body/Element1/Array1/a:Foo[a:Bar/text()='corner-bar-and-grill']/*[self::a:Value1 or self::a:Value2]
- 获取
ValueA:
/s:Envelope/s:Body/Element1/Array1/a:Foo[a:Bar/text()='corner-bar-and-grill']/*/*[self::a:MyArray]//a:MyArrayElement//a:ValueA
合并方案
基础合并版本(兼容XPath 1.0)
直接用XPath的**管道符|**连接两个表达式,同时优化第二个表达式的路径(去掉冗余的/*/*[self::a:MyArray],直接指定a:MyArray):
/s:Envelope/s:Body/Element1/Array1/a:Foo[a:Bar/text()='corner-bar-and-grill']/*[self::a:Value1 or self::a:Value2] | /s:Envelope/s:Body/Element1/Array1/a:Foo[a:Bar/text()='corner-bar-and-grill']/a:MyArray//a:MyArrayElement/a:ValueA
简洁优化版本(XPath 2.0+)
如果使用的XPath版本支持分组语法,可以用括号复用前置路径,让表达式更简洁:
/s:Envelope/s:Body/Element1/Array1/a:Foo[a:Bar='corner-bar-and-grill']/(a:Value1 | a:Value2 | a:MyArray//a:MyArrayElement/a:ValueA)
注:这里用a:Bar='corner-bar-and-grill'替代了a:Bar/text(),因为当元素只有文本节点时,直接匹配元素等价于匹配其文本内容,写法更简洁。
说明
- 管道符
|的作用是合并两个节点集,返回所有匹配到的节点的并集。 - 原XML中的标签不匹配问题会影响解析,务必修正
<a:Bar>的闭合标签为</a:Bar>。
内容的提问来源于stack exchange,提问作者user1126515
相关产品推荐
相关产品推荐

