Как перебирать сегменты простого текста с помощью анализатора Jericho HTML
Для элемента Иерихона я пытаюсь выяснить, как перебрать все дочерние узлы, будь то элемент или простой текст.
Теперь есть Element.getNodeIterator(), но он ссылается на ВСЕХ потомков в Элементе, а не только на первых потомков.
Мне нужен эквивалент Element.getChildSegments(). Есть идеи?
Спасибо
2 ответа
Все сегменты простого текста, не входящие ни в какие дочерние элементы, правильно?
public static Iterator<Segment> directPlainTextChildren(Element elem) {
final Iterator<Segment> it = elem.getContent().getNodeIterator();
final List<Segment> results = new LinkedList<Segment>();
final List<Element> children = elem.getChildElements();
while (it.hasNext()) {
Segment cur = it.next();
if (!(cur instanceof Tag) && !(cur instanceof CharacterReference)) {
for (Element child : children)
if (child.contains(cur)) continue;
results.add(cur);
}
}
return results.iterator();
}
Элемент должен иметь несколько прямых потомков, а метод Element::contains(Segment) - это просто проверка границ, поэтому производительность должна быть адекватной.
edit: если вы хотите добавить возможность повторять все прямые дочерние сегменты, это выглядело бы так:
public static Iterator<Segment> getChildSegments(Element elem) {
final Iterator<Segment> it = elem.getContent().getNodeIterator();
final List<Segment> results = new LinkedList<Segment>();
final List<Element> children = elem.getChildElements();
while (it.hasNext()) {
Segment cur = it.next();
if (cur instanceof CharacterReference)
results.add(cur);
else if (cur instanceof Tag) {
if (cur instanceof StartTag)
results.add(((StartTag)cur).getElement());
}
else {
for (Element child : children)
if (child.contains(cur)) continue;
results.add(cur);
}
}
return results.iterator();
}
Используя методологию из Gunslinger47, приведенную выше, следующее возвращает непосредственные (первый потомок) дочерние сегменты для элемента Elem:
public static List<Segment> getChildSegments(Element elem) {
final Iterator<Segment> it = elem.getContent().getNodeIterator();
final List<Segment> results = new LinkedList<Segment>();
final List<Element> children = elem.getChildElements();
while (it.hasNext()) {
Segment cur = it.next();
if (!(cur instanceof Tag) && !(cur instanceof CharacterReference) && !cur.isWhiteSpace()) {
boolean enclosed = false;
for (Element child : children) {
if (child.encloses(cur)) {
enclosed = true;
}
}
if (!enclosed) results.add(cur);
} else {
for (Element child : children) {
if (child.getStartTag().equals(cur)) {
results.add(cur);
break;
}
}
}
}
return results;
}