【问题标题】:How to select elements with only whitespace with Jsoup?如何使用 Jsoup 选择只有空格的元素?
【发布时间】:2015-07-30 12:25:57
【问题描述】:

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

给定 html:<html><body><p> </p></body></html>

使用 :empty 不会选择我假设的 p,因为其中有一个 " " 文本节点

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

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

也许我错过了什么?

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

【问题讨论】:

  • 如果没有某种解决方法,这将不起作用(至少在当前版本中)。正如您所说:空白已修剪 - 可以使用element.text().isEmpty() 进行检查,这将返回true。最好的解决方案是在Jsoup's Github issuesopen an issue
  • @ollo 这是一个涉及 Jsoup API 的解决方法:stackoverflow.com/a/35012778/363573
  • 感谢您的提示。

标签: java jsoup


【解决方案1】:

CSS 选择器只能匹配特定类型的节点:元素。选择器找不到 cmets 或文本节点。要查找只有空格的元素,我们必须依赖 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

【讨论】:

    猜你喜欢
    • 2011-09-23
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2012-05-28
    • 2015-02-19
    • 2015-10-05
    • 1970-01-01
    相关资源
    最近更新 更多