Jsoup: получить все элементы перед определенным элементом / удалить все элементы после определенного элемента - PullRequest
2 голосов
/ 23 января 2020

Предположим, у меня есть 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="pet">, которые предшествуют <div class="friends-pets">. Есть ли способ сделать это с Jsoup? Я знаю, что я могу получить всех питомцев, таких как:

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

, но это будет включать и дополнительных питомцев. Мне было интересно, смогу ли я выбрать только указанных выше животных или просто удалить указанных ниже животных, а затем использовать этот код?

Ответы [ 3 ]

1 голос
/ 03 февраля 2020

Существует очень простой способ сделать это с помощью одного селектора:

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

Это работает при использовании селектора :not() , когда .friends-pets ~ .pet находит каждый div после .friends-pets класс. Затем он исключает их из остальных совпадений классов .pet.

См. Работающий онлайн-пример здесь: try.jsoup

1 голос
/ 24 января 2020

Объяснение в комментариях:

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);
0 голосов
/ 24 января 2020

Я собираюсь проверить ответ Кристиана, но попробовав решить это сам, я придумаю следующий:

//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);
     }
}

Если вы считаете, что с этим ответом что-то не так, пожалуйста, дайте я знаю. Если у вас есть причины, по которым я должен использовать один из двух текущих ответов над другим, пожалуйста, оставьте комментарий!

...