简体   繁体   English

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

[英]XPath - attribute wildcard not returning element with attribute named value

I am trying to use XPath (Java) to get all unknown nodes based on unknown attributes starting with a specific value. 我正在尝试使用XPath(Java)来获取所有未知节点,这些节点基于以特定值开头的未知属性。 For some reason, it is not returning a node that contains an attribute named value . 由于某种原因,它不返回包含名为value的属性的节点。 I also tested at www.freeformatter.com/xpath-tester.html and got the same result. 我还在www.freeformatter.com/xpath-tester.html进行了测试,得到了相同的结果。 Here is what I have: 这是我有的:

XML: XML:

<div>
    <object data="/v1/assets/mp4Video-1" type="video/mp4">
        <param name="webmSource" value="/v1/assets/webmVideo-1" type="REF"/>
    </object>
</div>

XPath Expression: XPath表达式:

//*[starts-with(@*, '/v1/assets/')]

Results - returns the <object> , but not the <param> . 结果 -返回<object> ,但不返回<param>

Now, if I change the XPath expression to //*[starts-with(@*, '/v1/assets/') or starts-with(@value, '/v1/assets/')] , it returns both as expected. 现在,如果我将XPath表达式更改为//*[starts-with(@*, '/v1/assets/') or starts-with(@value, '/v1/assets/')] ,它将两者都返回为预期。

I guess my question is, what is it about the value attribute that causes XPath to not properly recognize it as an attribute, or to not return the element when the value attribute contains the value I am querying for? 我想我的问题是, value属性是什么导致XPath无法正确识别它作为属性,或者当value属性包含我要查询的值时不返回元素?

The reason why your original path expression: 您的原始路径表达式的原因:

//*[starts-with(@*, '/v1/assets/')]

does not work has to do with how functions in XPath 1.0 cope with more nodes than expected. 不起作用与XPath 1.0中的函数如何处理比预期更多的节点有关。 The starts-with() function expects a single node as its first argument, and a string (or a node that evaluates to a string) as its second argument. starts-with()函数需要将单个节点作为其第一个参数,并将字符串(或计算为字符串的节点)作为其第二个参数。

But in the expression above, starts-with() is handed a set of attribute nodes, @* , as its first argument. 但是在上面的表达式中, starts-with()被赋予一属性节点@*作为其第一个参数。 In this case, only the first of those attribute nodes is used by this function. 在这种情况下,此函数仅使用这些属性节点中的第一个 All other nodes in the set are ignored. 集合中的所有其他节点都将被忽略。 Since the order of attributes is not defined in XML, the XPath engine is free to choose any attribute node to be used in the function. 由于属性的顺序未在XML中定义,因此XPath引擎可以自由选择要在函数中使用的任何属性节点。 But your specific XPath engine (and many others) appear to consistently use the first attribute node, in the order of their appearance. 但是您的特定XPath引擎(以及许多其他引擎)似乎始终按照其外观的顺序使用第一个属性节点。

To illustrate this (and to prove it), change your input document to 为了说明这一点(并证明它),请将输入文档更改为

<div>
    <object data="other" type="/v1/assets/mp4Video-1">
        <param name="/v1/assets/webmVideo-1" value="other" type="REF"/>
    </object>
</div>

as you can see, I have changed the order of attributes, and the attribute containing /v1/assets/ is now the second attribute of the object element, and vice versa for the param element. 你可以看到,我已经改变属性的顺序,并且包含属性/v1/assets/现在是第二属性object元件的,反之亦然param元件。 Using this input document, your original XPath expression will only return the param element. 使用此输入文档,原始XPath表达式将仅返回param元素。

Again, this behaviour is not necessarily consistent between different XPath engines! 同样,这种行为在不同的XPath引擎之间不一定是一致的! Using other implementations of XPath might yield different results. 使用XPath的其他实现可能会产生不同的结果。


The XPath expression that does what you need is 执行所需操作的XPath表达式

//*[@*[starts-with(., '/v1/assets/')]]

in plain English, it says 用简单的英语说,它说

select elements anywhere in the document, but only if, among all attribute nodes of an element, there is an attribute whose value starts with "/v1/assets/". 选择文档中任何位置的元素,但仅当元素的所有属性节点中都有一个值以“/ v1 / assets /”开头的属性时。

Try 尝试

//@*[starts-with(., '/v1/assets/')]

Returns all the attributes 返回所有属性

//*[@*[starts-with(., '/v1/assets/')]]

Returns all the Elements 返回所有元素

This will search all attributes for all nodes. 这将搜索所有节点的所有属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM