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

使用DaisyDiff对比HTML能否保留原标记?现遇标记丢失问题

解决DaisyDiff对比HTML丢失标签的问题

嘿,我之前也跟这个老掉牙的DaisyDiff打过交道,文档稀缺得让人头疼!你遇到的标签丢失问题,根源在于DaisyDiff默认会把div这类容器标签当成"无意义"的结构节点,直接跳过它们去对比内部文本。不过咱们可以通过自定义标签比较器来搞定这个问题。

步骤1:自定义TagComparator

创建一个继承自DefaultTagComparator的类,告诉DaisyDiff哪些标签需要被保留并参与结构对比:

import org.xml.sax.helpers.DefaultTagComparator;

public class CustomTagComparator extends DefaultTagComparator {
    @Override
    public boolean isTagImportant(String namespaceURI, String localName) {
        // 添加你想要保留的标签,比如div、html、span等
        switch (localName) {
            case "div":
            case "html":
            case "span":
                return true;
            // 其他标签沿用默认逻辑
            default:
                return super.isTagImportant(namespaceURI, localName);
        }
    }
}

这个方法的作用是标记哪些标签是"重要"的——只有被标记为重要的标签,DaisyDiff才会保留它们的结构,否则会直接穿透到子节点。

步骤2:修改diffHTML调用代码

之前你传入的第4个参数是null,现在换成咱们自定义的TagComparator:

String html1 = "<div>Hello</div>";
String html2 = "<div>Bye</div>";
try {
    StringWriter finalResult = new StringWriter();
    SAXTransformerFactory tf = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
    TransformerHandler result = tf.newTransformerHandler();
    result.getTransformer().setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    result.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
    result.getTransformer().setOutputProperty(OutputKeys.METHOD, "html");
    result.getTransformer().setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    result.setResult(new StreamResult(finalResult));
    ContentHandler postProcess = result;
    
    // 关键:使用自定义TagComparator
    TagComparator customTagComparator = new CustomTagComparator();
    DaisyDiff.diffHTML(new InputSource(new StringReader(html1)), 
                       new InputSource(new StringReader(html2)), 
                       postProcess, 
                       customTagComparator, 
                       Locale.GERMAN);
    
    System.out.println(finalResult.toString());
} catch (SAXException | IOException e) {
    e.printStackTrace();
}

为什么这样能解决问题?

DaisyDiff的DefaultTagComparator默认只把<p>、<h1>这类"内容型"标签视为重要,而<div>、<html>这类容器标签会被忽略——对比时直接跳过这些标签,只处理内部的文本节点。通过自定义比较器,我们把需要保留的标签加入"重要列表",工具就会完整保留这些标签的结构,只在标签内部对比文本差异。

测试你给出的例子,现在输出会是:

<div><span class="removed">Hello</span><span class="added">Bye</span></div>

完全符合你的预期!

额外提示

  • 如果需要保留其他标签(比如<section>、<article>),直接在isTagImportant方法里添加对应的case即可。
  • 尽量使用DaisyDiff的最新稳定版本(虽然它很久没更新了,但新版本修复了一些老bug)。

内容的提问来源于stack exchange,提问作者Matthias Wünsch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:14:57