我正在尝试使用XPath(Java)根据以特定值开头的未知属性获取所有未知节点。由于某种原因,它不会返回包含名为value
的属性的节点。我还在www.freeformatter.com/xpath-tester.html进行了测试并获得了相同的结果。这就是我所拥有的:
XML:
<div>
<object data="/v1/assets/mp4Video-1" type="video/mp4">
<param name="webmSource" value="/v1/assets/webmVideo-1" type="REF"/>
</object>
</div>
XPath表达式:
//*[starts-with(@*, '/v1/assets/')]
结果会返回<object>
,但不会返回<param>
。
现在,如果我将XPath表达式更改为//*[starts-with(@*, '/v1/assets/') or starts-with(@value, '/v1/assets/')]
,它将按预期返回。
我想我的问题是,value
属性是什么导致XPath无法正确识别它作为属性,或者当value
属性包含值I时不返回元素我在询问?
答案 0 :(得分:3)
原始路径表达式的原因:
//*[starts-with(@*, '/v1/assets/')]
不起作用与XPath 1.0中的函数如何处理比预期更多的节点有关。 starts-with()
函数需要将单个节点作为其第一个参数,并将字符串(或计算为字符串的节点)作为其第二个参数。
但是在上面的表达式中,starts-with()
将属性节点的{em> set 作为其第一个参数传递给@*
。在这种情况下,此函数仅使用这些属性节点的 first 。集合中的所有其他节点都将被忽略。由于属性的顺序未在XML中定义,因此XPath引擎可以自由选择要在函数中使用的任何属性节点。但是您的特定XPath引擎(以及许多其他引擎)似乎始终按照它们出现的顺序使用第一个属性节点。
为了说明这一点(并证明它),请将输入文档更改为
<div>
<object data="other" type="/v1/assets/mp4Video-1">
<param name="/v1/assets/webmVideo-1" value="other" type="REF"/>
</object>
</div>
如您所见,我更改了属性的顺序,包含/v1/assets/
的属性现在是object
元素的 second 属性,反之亦然param
元素。使用此输入文档,原始XPath表达式将仅返回param
元素。
同样,这种行为在不同的XPath引擎之间不一定是一致的!使用XPath的其他实现可能会产生不同的结果。
执行所需操作的XPath表达式
//*[@*[starts-with(., '/v1/assets/')]]
用简单的英语说,
在文档中的任何位置选择元素,但仅当元素的所有属性节点中都有一个值为“/ v1 / assets /".
的属性时
答案 1 :(得分:2)
尝试
//@*[starts-with(., '/v1/assets/')]
返回所有属性
//*[@*[starts-with(., '/v1/assets/')]]
返回所有元素
这将搜索所有节点的所有属性。