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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 07:15:05