我在xpath中寻找的东西可以做://foo[@n="$1"]//bar[@n="$2"]
可以返回$1
和$2
。或者至少给我<foo>
和<bar>
这里有更多细节,我有一个xml文档:
<xml>
<foo>
<a n="1">
<b n="1"/>
<b n="2"/>
</a>
</foo>
<a n="2">
<b n="1"/>
</a>
<a n="3">
<b n="1"/>
<foo>
<b n="2"/>
</foo>
<b n="3"/>
</a>
</xml>
我希望在<a>
和<b>
的n属性上生成一个字符串
所以我有xpath://a[@n]//b[@n]
然后,对于我得到的每个结果,我使用:./@n
和./ancestor::a/@n
来获取我想要的信息。
这很好用,但我需要更聪明的东西,因为我有很多这样的结构,需要自动生成xpath。
所以对于上面的例子,我正在寻找一些xpath,如://a[@n="$1"]//b[@n="$2"]
然后回复我:
`(1,1),(1,2),(2,1),(3,1),(3,2),(3,3)
答案 0 :(得分:3)
以下是一个XPath 1.0表达式,用于选择所有需要的n
属性:
//a[.//b]/@n | //a//b/@n
如果没有优化,上述表达式的评估至少会执行两次XML文档的完整遍历。
此XPath 1.0表达式可能更有效:
//*[self::a and .//b or self::b and ancestor::a]/@n
如果可以确保每个a
都有b
后代,则可以简化这两种表达式。
他们分别成为:
//a/@n | //a//b/@n
和
//*[self::a or self::b and ancestor::a]/@n
如果可以保证每个a
都有一个后代b
且每个b
都有一个祖先a
,则可以进一步简化。:
//*[self::a or self::b]/@n
在单个XPath 1.0表达式中无法获取所有需要属性的字符串值。需要使用上述表达式之一获取所有属性,然后在每个选定的属性上应用第二个XPath表达式:string()
。
在Xpath 2.0中,可以使用单个表达式获取所需属性的所有字符串值 - 只需使用/string(.)
附加每个表达式
例如,对于最简单的一个:
//(a|b)/@n/string(.)
<强>更新强>:
OP已澄清他的问题。现在我们知道他希望产生这个结果:(1, 1), (1, 2), (2, 1), (3, 1), (3, 2), (3, 3)
使用单个XPath 1.0表达式无法生成所需结果。
以下XPath 2.0表达式生成所需结果:
for $a in //a[@n and .//b[@n]],
$b in $a//b[@n]
return
concat('(', $a/@n, ',', $b/@n, ') ')