Combine XPATH predicate with position

会有一股神秘感。 提交于 2019-11-30 14:06:24

问题


I have a collection of div elements that have the class media-gallery-item.
I would like to select element number x.

When just selecting all items, I get 5 results

$x("//div[@id='content-area']//div[@class='media-gallery-item']")

Now I want to be able to select item number 2, but I can't figure out how to combine the two properly:

$x("//div[@id='content-area']//div[@class='media-gallery-item'][2]")

$x("//div[@id='content-area']//div[@class='media-gallery-item'
                                   and position() = 2]")

I know these don't make a lot of sense since it's not an actual AND, but more like: "filter according to this first, then select the 2nd match". The goal of this is to keep on selecting things (e.g. in the second element, get me the href attribute of the a element)


回答1:


Step-by-step answer.

To select elements with a div[@id='content-area'] ancestor, which are the second children of their respective parents use:

//div[@id='content-area']//div[2]

To select second (in document order) div element with a div[@id='content-area'] ancestor use:

(//div[@id='content-area']//div)[2]

Do note the difference.

Then, to select elements, which are second children of their respective parents, providing they have a class 'media-gallery-item' use:

//div[@id='content-area']//div[2][@class='media-gallery-item']

To select elements, which are the second from those children (of their respective parents) that have a class media-gallery-item:

//div[@id='content-area']//div[@class='media-gallery-item'][2]

To select second (in document order) div element with a div[@id='content-area'] ancestor, providing it has media-gallery-item class:

(//div[@id='content-area']//div)[2][@class='media-gallery-item']

To select second (in document order) from all div element with a div[@id='content-area'] ancestor and a media-gallery-item class:

(//div[@id='content-area']//div)[@class='media-gallery-item'][2]

Spec quotes as suggested by @Alejandro:

A predicate filters a node-set with respect to an axis to produce a new node-set. For each node in the node-set to be filtered, the PredicateExpr is evaluated with that node as the context node, with the number of nodes in the node-set as the context size, and with the proximity position of the node in the node-set with respect to the axis as the context position

http://w3.org/TR/xpath/#predicates

The proximity position of a member of a node-set with respect to an axis is defined to be the position of the node in the node-set ordered in document order if the axis is a forward axis and ordered in reverse document order if the axis is a reverse axis

http://w3.org/TR/xpath/#dt-proximity-position

Bottom line is that the position predicate works with respect to the axis. And you need parenthesis to explicitly declare the priority. Thus not the child axis, but the node-set after resolving descendant-or-self axis will be considered, when calculating position.




回答2:


Turns out: parenthesis!

(//div[@id='content-area']//div[@class='media-gallery-item'])[2] 

works




回答3:


It looks like your accessing attributes in the wrong way. Try to use

/div[@id='content-area' and @class='media-gallery-item'][2]


来源:https://stackoverflow.com/questions/4961349/combine-xpath-predicate-with-position

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!