Traverse elements that aren't children between

2019-07-19 22:16发布

This question already has an answer here:

Using Nokogiri, I'm trying to figure out the best way to select div elements that match a css class between two other div elements. Here's some sample HTML of what I'm working with:

<div class="date">
  <span>Today</span>
</div>
<div class="random"></div>
<div class="preferred"></div>
<div class="preferred"></div>
<div class="preferred"></div>
<div class="random"></div>
<div class="date">
  <span>Tomorrow</span>
</div>

What I want is to basically return the divs whose class is "preferred" between the divs with "date" class.

I can grab my starting point with something like:

doc.at("span:contains('Today')").parent

However, I'm not sure the best way to get its next_elements based on class up until the next div.date.

1条回答
可以哭但决不认输i
2楼-- · 2019-07-19 22:36

I'm applying the Kaysian method for obtaining the intersection of a set (as described in the duplicate link of this question) in the context of your specific scenario (and not considering any other external context which you didn't include in your question).

You need to define two sets:

  1. A: //div[preceding-sibling::div[@class='date']] (all div elements which have a preceding sibling div of the date class.)
  2. B: //div[following-sibling::div[@class='date']] (all div elements which have a following sibling div of the date class.)

The intersection of those two sets is the solution to your problem. The formula of the Kaysian method is: A [ count(. | B) = count(B) ]. Applying that to your problem, the result you need is:

//div[preceding-sibling::div[@class='date']][count( . | //div[following-sibling::div[@class='date']] ) = count(//div[following-sibling::div[@class='date']] ) ]

This will select the following elements:

<div class="random"></div>
<div class="preferred"></div>
<div class="preferred"></div>
<div class="preferred"></div>
<div class="random"></div>

If you apply this expression in a global context where there are other <div class="date"> elements, you will have to adapt it and change your sets so that they uniquely identify the bordering elements.

查看更多
登录 后发表回答