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
相关产品推荐
相关产品推荐

