如何用Jsoup选择只有空格的元素?

时间:2015-05-18 20:57:28

标签: java jsoup

我在选择只有空格的元素时遇到了问题。

鉴于html:<html><body><p> </p></body></html>

使用:empty不选择p I&m;假设因为有一个文本节点&#34; &#34;在其中

但是,:matchesOwn(^\\s+$)不会选择它,因为似乎JSoup在对照正则表达式模式测试之前对文本执行了trim()

:matchesOwn(^$)会选择它,但也会选择没有文字节点且不空的元素

也许我错过了什么?

:matchesOwn根本不应修剪,因为它使用正则表达式并且应评估整个文本

1 个答案:

答案 0 :(得分:0)

CSS选择器只能匹配特定类型的节点:元素。选择器无法找到注释或文本节点。为了找到只有空格的元素,我们必须依赖Jsoup API。

我们将查找仅具有一个唯一文本节点子节点的节点。此唯一文本节点必须与以下正则表达式^\s+$匹配。要获取(未修剪的)文字,我们会调用TextNode#getWholeText方法。

以下是如何操作:

String html = "<html><body><div><p> </p><p> </p><span>\n\t\n   </span></div><span></span></body></html>";

Document doc = Jsoup.parse(html);

final Matcher onlyWhitespaceMatcher = Pattern.compile("^\\s+$").matcher("");
new NodeTraversor(new NodeVisitor() {

    @Override
    public void head(Node node, int depth) {
        List<Node> childNodes = node.childNodes();
        // * We're looking for nodes with one child only otherwise we move on
        if (childNodes.size() != 1) {
            return;
        }

        // * This unique child node must be a TextNode
        Node uniqueChildNode = childNodes.get(0);
        if (uniqueChildNode instanceof TextNode == false) {
            return;
        }

        // * This unique TextNode must be whitespace only
        if (onlyWhitespaceMatcher.reset(((TextNode) uniqueChildNode).getWholeText()).matches()) {
            System.out.println(node.nodeName());
        }
    }

    @Override
    public void tail(Node node, int depth) {
        // void
    }
}).traverse(doc);
// Instead of traversing the whole document,
// we could narrow down the search to its body only with doc.body()

输出

p
p
span