You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取元素的所有子文本节点(含间接子节点)?

问题:用Jsoup获取元素的所有嵌套子文本节点

我们需要获取某一元素的所有子文本节点,包括直接子文本节点和间接子文本节点(如孙节点、曾孙节点等)。但Jsoup的Element类提供的textNodes()方法仅返回直接子文本节点,无法满足需求。

示例HTML

<html>
    <head/>
    <body>
        <div class="erece mtmhp">
            <a href="http://www.stackoverflow.com">
                <span>Content 1</span>
                <span>Content 2</span>
            </a>
        </div>
    </body>
</html>

我们的目标是从中分别获取Content 1和Content 2这两个文本节点。

初始示例代码(无法满足需求)

import java.io.File;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;

public class TextNodeExpt {
    public static void main(String[] args) throws Exception {

        File fileObj = new File(args[0]);
        Document document = Jsoup.parse(fileObj, "UTF-8");

        Elements divs = document.select("div.erece.mtmhp");

        displaySubtendingTextNodes(divs);
    }

    protected static void displaySubtendingTextNodes(Elements divs) {
        for (Element div : divs) {
            Elements anchors = div.select("a");
            for (Element anchor : anchors) {
                List<TextNode> textNodes = anchor.textNodes();
                System.out.println(textNodes.size() + " text nodes found");
                for(TextNode tn : textNodes) {
                    System.out.println("[" + tn.getWholeText() + "]");
                    }
            }
        }
    }
}

这段代码无法获取目标文本节点,因为anchor.textNodes()仅返回<a>标签的直接子文本节点,而<a>的直接子节点是<span>元素,没有直接文本节点。

解决方法:递归遍历所有子节点

通过递归遍历目标元素的所有子节点,筛选出非空白的文本节点,即可获取所有嵌套的子文本节点。完整实现如下:

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.Elements;

public class TextNodeExpt {
    public static void main(String[] args) throws Exception {

        File fileObj = new File(args[0]);
        Document document = Jsoup.parse(fileObj, "UTF-8");

        Elements divs = document.select("div.erece.mtmhp");

        displayAllSubtextNodes(divs);
    }

    protected static void displayAllSubtextNodes(Elements divs) {
        for (Element div : divs) {
            Elements anchors = div.select("a");
            for (Element anchor : anchors) {
                List<TextNode> allTextNodes = new ArrayList<>();
                textNodes(anchor, allTextNodes);
                System.out.println(allTextNodes.size() + " text nodes found");
                for(TextNode tn : allTextNodes) {
                    System.out.println("[" + tn.getWholeText() + "]");
                }
            }
        }
    }

    protected static void textNodes(Node targetNode, List<TextNode> nodeList) {
        for (Node childNode : targetNode.childNodes()) {
            if (childNode instanceof TextNode && !((TextNode) childNode).isBlank()) {
                nodeList.add((TextNode)childNode);
            }
            else {
                textNodes(childNode, nodeList);
            }
        }
    }
}

代码说明

  • textNodes方法递归遍历目标节点的所有子节点,判断如果是文本节点且非空白,就添加到传入的列表中
  • 调用时初始化一个空列表,传入方法后就能得到所有嵌套的文本节点
  • 运行这段代码后,会正确输出Content 1和Content 2

内容的提问来源于stack exchange,提问作者Sandeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:47:54