
JSoup 默认会压缩文本节点中的空白字符(如连续空格、换行符),导致断言失败;本文介绍通过 wholeText() 方法精准获取含原始空白的文本内容,并纠正常见选择器误用问题。
jsoup 默认会压缩文本节点中的空白字符(如连续空格、换行符),导致断言失败;本文介绍通过 `wholetext()` 方法精准获取含原始空白的文本内容,并纠正常见选择器误用问题。
在使用 JSoup 进行 HTML 解析与测试验证时,一个常见痛点是:原始 HTML 中的多个连续空格(如 "ABC 123" 中的两个空格)会被自动折叠为单个空格。这是因为 JSoup 的 text() 方法会调用其内部的“规范化文本”逻辑(基于 Node#wholeText() 的简化封装),它会合并相邻文本节点并标准化空白(类似浏览器渲染前的 DOM 文本归一化),而非原样返回原始字符序列。
例如,以下测试会失败:
Document doc = Jsoup.parse("<span id="sp1"><strong>ABC 123</strong></span>");
String actual = doc.select("span#sp1").text(); // 返回 "ABC 123"(两个空格变一个)
assertThat(actual).isEqualTo("ABC 123"); // ❌ 断言失败
⚠️ 注意:outputSettings().prettyPrint(false) 对此无效——该设置仅控制 doc.html() 或 element.html() 输出时的缩进与换行格式,不影响 text() 方法对文本内容的空白处理逻辑。
✅ 正确解法:使用 Element#wholeText() 方法
wholeText() 会递归收集当前元素内所有文本节点(包括 内部的文本),保持各文本节点间的原始空白(含空格、制表符、换行),且不进行跨节点空白合并。它更贴近“源码级文本提取”,适用于精确比对场景:
Document doc = Jsoup.parse("<span id="sp1"><strong>ABC 123</strong></span>");
// ✅ 推荐:使用 getElementById 或 selectFirst 获取单个 Element,再调用 wholeText()
Element sp1 = doc.getElementById("sp1");
String actual = sp1.wholeText(); // 返回 "ABC 123"(保留双空格)
assertThat(actual).isEqualTo("ABC 123"); // ✅ 通过
// 或等价写法(注意:务必用 selectFirst 而非 select)
String actual2 = doc.selectFirst("span#sp1").wholeText();
? 关键注意事项:
- select("...") 返回 Elements(集合),而 text() 是对整个集合所有元素文本拼接后规范化——易引发歧义;应优先使用 selectFirst() 或 getElementById() 获取单个 Element。
- wholeText() 不包含 HTML 标签,仅返回纯文本(含原始空白),因此无需额外清洗,可直接用于断言。
- 若需同时校验结构与空白(如验证 是否存在),应结合 html() + 自定义空白敏感解析,或改用 outerHtml() 配合正则/AST 比对。
总结:当测试依赖 HTML 原始空白语义时,放弃 text(),拥抱 wholeText();并确保通过精确选择器获取单一元素,避免集合操作引入意外行为。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











