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

