Как перебирать сегменты простого текста с помощью анализатора 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;
}
Другие вопросы по тегам