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

Android中用Jsoup提取父元素文本但排除子元素文本的问题

提取父元素的直接文本(排除子元素文本)

问题描述

我需要在Java中提取父元素的直接文本并赋值给message变量,但当前代码会同时提取子元素的文本,返回内容为“Message Data”。在JavaScript cheeriojs中已经实现了类似逻辑且可正常运行,请求协助解决Java端的问题。

相关代码

HTML代码

<span class="milestone-primaryMessage beta">
Message <span class="nowrap">Data</span>
</span>

原Java代码(存在问题)

String message = ele.select(".milestone-primaryMessage").text();
String data = ele.select(".milestone-primaryMessage > .nowrap").text();

可用的JavaScript cheeriojs代码

const message = $($(el).find(".milestone-primaryMessage").contents().get(0)).text().trim(),
const data = $(el).find(".milestone-primaryMessage > .nowrap").text().trim()

解决方案

Java中使用jsoup时,Element.text()方法会递归获取所有子节点的文本并拼接,因此会包含子元素的内容。要实现和cheerio类似的逻辑,需要直接遍历父元素的子节点,筛选出文本节点(TextNode),再提取其内容:

修正后的Java代码

// 获取目标父元素
Element primaryMsgEle = ele.selectFirst(".milestone-primaryMessage");
String message = "";
if (primaryMsgEle != null) {
    // 遍历子节点,找到第一个文本节点
    for (Node node : primaryMsgEle.childNodes()) {
        if (node instanceof TextNode) {
            // 提取文本并去除首尾空白
            message = ((TextNode) node).text().trim();
            break; // 找到目标节点后停止遍历
        }
    }
}
// 子元素文本提取保持不变
String data = ele.selectFirst(".milestone-primaryMessage > .nowrap").text().trim();

或者使用Stream API简化代码:

Element primaryMsgEle = ele.selectFirst(".milestone-primaryMessage");
String message = primaryMsgEle != null ? 
    primaryMsgEle.childNodes().stream()
        .filter(node -> node instanceof TextNode)
        .map(node -> ((TextNode) node).text().trim())
        .findFirst()
        .orElse("") : "";

说明

  • cheerio的contents()方法会返回元素的所有子节点(包括文本节点和元素节点),get(0)直接取到了父元素的第一个文本节点;
  • Java jsoup中通过childNodes()获取所有子节点,再筛选出TextNode类型的节点,就能得到父元素的直接文本,避免包含子元素的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:47:33