Jsoup:获取某个元素之前的所有元素/删除某个元素之后的所有元素

Jsoup: get all elements before a certain element / remove all elements after a certain element

假设我 html 是这样的:

<div class="pets">
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="friends-pets">Your friends have these pets:</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
  <div class="pet">...</div>
</div>

我只想得到 <div class="friends-pets"> 之前的 <div class="pet">。有没有办法用 Jsoup 做到这一点?我知道我可以得到所有这样的宠物:

Element petsWrapper = document.selectFirst(".pets");
Elements pets = petsWrapper.select(".pet");

但这也包括额外的宠物。我想知道我是否只能 select 上面的宠物,或者只删除下面的宠物然后使用那个代码?

评论中的解释:

Element petsWrapper = document.selectFirst(".pets");
Elements pets = petsWrapper.select(".pet");
// select middle element
Element middleElement = petsWrapper.selectFirst(".friends-pets");
// remove from "pets" every element that comes after the middle element
pets.removeAll(middleElement.nextElementSiblings());
System.out.println(pets);

我要查看 Krystian 的回答,但在尝试自己解决这个问题后,我想到了这个:

//get all divs
Elements divElements = doc.select("div");
//valid pet divs will be here
List<Element> pets = new ArrayList<>();
for (Element divElement: divElements)  {
    if (divElement.className().equalsIgnoreCase("friends-pets")) {
       //invalid div, the cycle stops here 
       break;
     }

     if (divElement.className().contains("pet"))  {
        //if there has been no invalid div so far, adding a pet
        pets.add(divElement);
     }
}

如果您认为此回答有问题,请告诉我。如果您有理由说明为什么我应该使用当前两个答案中的一个而不是另一个,请也发表评论!

有一个非常简单的方法可以用一个选择器来完成:

.pet:not(.friends-pets ~ .pet)

这是通过使用 :not() selector.friends-pets ~ .pet.friends-pets class 之后找到每个 div 来实现的。然后它会从其余 .pet class 匹配中排除那些。

在此处查看有效的在线示例:try.jsoup