我正在寻找一种方法来连接两个任意的,有效的XPath表达式来构建一个新的XPath表达式。
实际上,我想在第一个XPath表达式的结果上应用第二个XPath表达式。
例如,请使用此XML:
<foo>
<bar>
<baz />
</bar>
<foo>
XPath表达式/foo
显然会返回根元素,而/bar
则不返回任何内容。但/bar
应用于/foo
的结果应返回<bar>
元素。
现在天真的实现只是使用字符串连接来构建/foo/bar
并评估它以获得<bar>
。这适用于这种特定情况。
现在我的问题是:它总是那么简单吗?是否有任何类型的XPath表达式,这不会导致有效的表达式或导致意外结果?
如果某些模糊的XPath表达式无法通过这种方式进行验证,那么这不是一个问题,但我希望常用的方法能够正常工作。
如果有问题:是否有任何类型的连接在更多情况下有效?
答案 0 :(得分:2)
在XPath 1.0 中,/
运算符要求左边的操作数是选择节点集的类型,右边的操作数是相对的XPath表达式 - 也是键入选择节点集。
因此,任何评估为简单值(number,string,boolean)的expr1
都不能用于/
的左侧。对于/
的右侧参数,这是完全正确的。
示例:
string(/foo)/bar
count(//foo)/bar
(/foo/baz = 3)/bar
/foo/count(bar)
在XPath 2.0 中,仍然需要在expr1/expr2
expr1
中评估一个节点集。但是,expr2
可以是函数调用。因此,以下内容有效且结果有意义:
/foo/bar/string-length(.)
(:一个整数序列,它是每个/foo/bar
节点的字符串长度:)
/foo/bar/name(.)
(:一系列字符串,它们是每个/foo/bar
节点的名称:)
foo/bar/count(node())
(:一个整数序列,它是每个/foo/bar
节点的子节点数:)
可以使用其他连接器组合两个表达式以产生第三个:
在XPath 1.0和XPath 2.0中:
union 运算符:
expr1 | expr2
比较运算符:
expr1 = expr2
expr1 >= expr2
expr1 < expr2
expr1 <= expr2
expr1 != expr2
布尔运算符和not()
函数:
not(expr1)
expr1 and expr2
expr1 or expr2
在XPath 2.0中:
运营商except
,intersect
union