代码之家  ›  专栏  ›  技术社区  ›  Richard H

如何使用Jericho HTML解析器迭代纯文本段

  •  0
  • Richard H  · 技术社区  · 15 年前

    对于jericho元素,我试图了解如何循环所有子节点,无论是元素还是纯文本。

    现在有element.getnodeiterator(),但它引用元素中的所有子代,而不仅仅是第一个子代。

    我需要element.getchildsegments()的等效项。有什么想法吗?

    谢谢

    2 回复  |  直到 15 年前
        1
  •  0
  •   Gunslinger47    15 年前

    所有不在任何子元素中的纯文本段,对吗?

    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();
    }
        2
  •  0
  •   Richard H    15 年前

    使用上面gunslinger47中的方法,以下返回元素elem的immediate(第一个子代)子段:

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