简体   繁体   中英

Xpath : Get specific preceding siblings for each specific element

Here is the format of my HTML :

<div class="menu">
    <h3 class="menu_item_title">Title of first category</h3>
    <div class="menu_item">Item 1</div>
    <div class="menu_item">Item 2</div>
    <div class="menu_item">Item 3</div>
    <h3 class="menu_item_title">Title of second category</h3>
    <div class="menu_item">Item 4</div>
    <div class="menu_item">Item 5</div>
    <div class="menu_item">Item 6</div>
    <div class="menu_item">Item 7</div>
    <div class="menu_item">Item 8</div>
    <div class="menu_item">Item 9</div>
</div>

I want to have for each "menu_item" the H3 "menu_item_title" preceding element. So for the first 3 elements I want to find "Title of first category" for the remaining ones I want to have "Title of second category".

In this example I have only two categories, but in reality there are much more than that.

I tried to do something like :

//div[contains(concat(" ", normalize-space(@class), " "), " menu_item ")]/preceding::h3[contains(concat(" ", normalize-space(@class), " "), " menu_items_title ")]

but it didnt work out.

Can someone send me some magic ;) ?

I'm not sure if you want to get as result each h3 element multiple times (once for each following menu_item ) or only once, but in case of latter the following XPath

//div[@class='menu_item']/preceding::h3[@class='menu_item_title']

produces the result

<h3 class="menu_item_title">Title of first category</h3>
<h3 class="menu_item_title">Title of second category</h3>

Note that also the approach mentioned in your question will have the same result when you adjust the typo you have here: menu_items_title should be menu_item_title at the part preceding::h3[contains(concat(" ", normalize-space(@class), " "), " menu_items_title ")]

"I want to have a query which outputs 3 times : Title of first category And 6 times : Title of second category "

That can't be done in pure XPath 1.0 only, you'll need some PHP to accomplish this task. One possible way is by executing XPath that return the div elements first :

//div[contains(concat(" ", normalize-space(@class), " "), " menu_item ")]

...then iterate through the result and execute the following relative XPath on each div to get the corresponding h3 element :

./preceding-sibling::h3[contains(concat(" ", normalize-space(@class), " "), " menu_item_title ")][1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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