如何在Dart中解析带样式和换行的HTML内容?
要保留HTML解析后的原始换行效果,核心是不要直接调用DOM节点的.text属性(该属性默认会合并所有空白字符,丢失换行),需要手动遍历DOM节点,针对块级元素、<br>标签主动插入换行符,具体实现如下:
实现步骤
- 先梳理需要触发换行的HTML标签:包含
<br>以及所有块级元素(p、div、h1~h6、li、blockquote、tr等,可根据业务需求增删) - 递归遍历DOM树:
- 文本节点直接保留原始文本内容,不做空白合并
- 元素节点先处理所有子节点,若当前节点属于需换行的标签,在子节点内容末尾追加一个换行符
- 最后对生成的文本做多余换行的裁剪,避免嵌套块级元素产生的连续空行
示例代码
import 'package:html/parser.dart'; import 'package:html/dom.dart'; String parseHtmlWithLineBreak(String htmlStr) { // 定义需要换行的标签集合 const lineBreakTags = {'br', 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'li', 'blockquote', 'tr'}; final buffer = StringBuffer(); void traverse(Node node) { if (node is Text) { // 文本节点直接写入,保留原始空白 buffer.write(node.data); return; } if (node is Element) { // 先处理所有子节点 for (var child in node.nodes) { traverse(child); } // 匹配到换行标签则加换行 if (lineBreakTags.contains(node.localName?.toLowerCase())) { buffer.writeln(); } } } final document = parse(htmlStr); // 从body节点开始遍历 traverse(document.body ?? document.documentElement!); // 可选:裁剪连续超过2个的换行,避免过多空行 return buffer.toString().replaceAll(RegExp(r'\n{3,}'), '\n\n').trim(); }
调用示例
void main() { const testHtml = ''' <p>第一行内容</p> <div>第二行内容<br>第二行的换行内容</div> <p>第三行段落</p> '''; final result = parseHtmlWithLineBreak(testHtml); print(result); }
如果需要更贴近浏览器的渲染效果,可以额外处理<pre>、<code>标签的空白保留逻辑,在遍历到这类标签时直接保留全部原始格式即可。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

