XPath - 属性通配符不返回具有名为value的属性的元素

时间:2015-04-08 21:56:07

标签: java xml xpath

我正在尝试使用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时不返回元素我在询问?

2 个答案:

答案 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/')]]

返回所有元素

这将搜索所有节点的所有属性。