ошибка jsoup в Element.empty () - PullRequest
0 голосов
/ 14 января 2012

Я разместил это в группе Jsoup на google.groups, но, похоже, в последнее время там не так много активности, поэтому я попробую и здесь ...

Следующий код

final String html = "<html><head></head><body><div></div></body></html>";
Document doc = Jsoup.parse(html);
Element body = doc.body();
Element div = body.select("div").first();
body.empty();                   // <--- gives exception at line 56 below
// body.children().remove();    // does not give exception
body.appendChild(div);          // line 56, IndexOutOfBoundsException here

с Jsoup 1.6.1, дает мне исключение IndexOutOfBoundsException со следующей (частичной, верхние 7 строк) трассировкой стека

at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.remove(ArrayList.java:387)
at org.jsoup.nodes.Node.removeChild(Node.java:394)
at org.jsoup.nodes.Node.reparentChild(Node.java:420)
at org.jsoup.nodes.Node.addChildren(Node.java:402)
at org.jsoup.nodes.Element.appendChild(Element.java:225)
at webfilter.FilterY.<init>(FilterY.java:56)

здесь FilterY - мой класс, содержащий приведенный выше код.Если я использую body.children (). Remove () вместо body.empty (), он отлично работает.

Вопрос в том ... злоупотребляю ли я здесь Jsoup, или это действительно ошибка?

1 Ответ

1 голос
/ 29 февраля 2012

Да, вы используете библиотеку jSoup неправильно.Пройдемся строка за строкой:

Вы сохраняете ссылку на первого ребенка:

Element div = body.select("div").first();

Вы являетесьудаление всех дочерних узлов элемента:

body.empty();

И затем вы пытаетесь добавить удаленный дочерний узел:

body.appendChild(div);

Теперь проблема в последнем шаге, потому что, когда вы удалили все дочерние элементы, тогда в это время отношения родитель-потомок не разрываются, потому что body.empty(); просто вызывает метод clear(); java.util.List ион не нарушает никакой связи родитель-потомок, что не так, когда вы делаете body.children().remove(), и поэтому в следующем коде вы получаете упомянутое исключение, так как есть свисающая ссылка на дочерний узел:

 protected void removeChild(Node out) {
        Validate.isTrue(out.parentNode == this);
        int index = out.siblingIndex();
        childNodes.remove(index); // problem comes here
        reindexChildren();
        out.parentNode = null;
    }

Но , если вы сделаете что-то подобное, это будет работать:

Element div_child = doc.createElement("div");
body.appendChild(div_child); 
...