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

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

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

然而,:matchesOwn(^\\s+$)也不会选择它,因为 JSoup 似乎做了一个 trim()在根据正则表达式模式测试文本之前。

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

也许我遗漏了什么?

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

请您参考如下方法:

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 


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!