Как перебирать сегменты простого текста с помощью анализатора Jericho HTML - PullRequest
0 голосов
/ 25 октября 2009

Для элемента Иерихона я пытаюсь выяснить, как зациклить все дочерние узлы, будь то элемент или простой текст.

Теперь существует Element.getNodeIterator (), но он ссылается на ВСЕХ потомков в Элементе, а не только на первых потомков.

Мне нужен эквивалент Element.getChildSegments (). Есть идеи?

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 октября 2009

Используя методологию из 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;
}
0 голосов
/ 25 октября 2009

Все сегменты простого текста вне дочерних элементов, верно?

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) - это просто проверка границ, поэтому производительность должна быть адекватной.

редактирование: Если бы вы хотели добавить возможность повторять все прямые дочерние сегменты, это выглядело бы так:

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();
}
...