java - 是否可以使用 DaisyDiff 保留输入标记?

标签 java html diff

所以,我目前正在努力实现一个比较工具,它能够比较两个 HTML 文件。我做了一些研究并最终使用了 DaisyDiff。由于这个工具现在似乎有点过时了,我很难找到一些仍然有效的示例。我发现this quesion on Stackoverflow ,因为我不知道该传递什么作为第三个和第四个参数,这很有帮助。我的实现的当前状态:

String html1 = "<html class='foobar'>Hello</html>";
String html2 = "<html>Bye</html>";

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; 

    DaisyDiff.diffHTML(new InputSource(new StringReader(html1)), new InputSource(new StringReader(html2)), postProcess, null, Locale.GERMAN);

    System.out.println(finalResult.toString());

} catch (SAXException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

问题是,它实际上只比较纯文本,但它完全从输入中删除标记。例如,如果我将这两个字符串作为输入:

String first = "<div>Hello</div>"
String second = "<div>Bye</div>"

我期望这样的输出:

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

但我只得到这个:

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

最佳答案

所以,我终于让它发挥作用了。我发现this example code后在 Github 上,很明显,问题不是 ContentHandler,正如我怀疑的那样。因此,如果有人还需要比较一些 HTML,并且不想浪费几天时间来寻找一个好的(并且有效的)示例,那么我就是这样让它工作的。

首先,您需要下载NekoHTML Dependency ,它基本上是一个 HTML 解析器。

这就是我的导入 block 的样子

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Locale;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

import org.outerj.daisy.diff.helper.NekoHtmlParser;
import org.outerj.daisy.diff.html.HTMLDiffer;
import org.outerj.daisy.diff.html.HtmlSaxDiffOutput;
import org.outerj.daisy.diff.html.TextNodeComparator;
import org.outerj.daisy.diff.html.dom.DomTreeBuilder;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

这是我对 Differ 的完整实现,它不会删除实际的标记(请注意,这实际上不是我的代码,我只是得到了上面链接的示例!):

public static String diffHtml(String first, String second) throws TransformerConfigurationException, IOException, SAXException {

    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;

    Locale locale = Locale.getDefault();
    String prefix = "diff";

    NekoHtmlParser cleaner = new NekoHtmlParser();

    InputSource oldSource = new InputSource(new StringReader(first));
    InputSource newSource = new InputSource(new StringReader(second));

    DomTreeBuilder oldHandler = new DomTreeBuilder();
    cleaner.parse(oldSource, oldHandler);
    TextNodeComparator leftComparator = new TextNodeComparator(oldHandler, locale);

    DomTreeBuilder newHandler = new DomTreeBuilder();
    cleaner.parse(newSource, newHandler);
    TextNodeComparator rightComparator = new TextNodeComparator(newHandler, locale);

    HtmlSaxDiffOutput output = new HtmlSaxDiffOutput(postProcess, prefix);

    HTMLDiffer differ = new HTMLDiffer(output);
    differ.diff(leftComparator, rightComparator);

    System.out.println(finalResult.toString());

    return finalResult.toString();
}

哦,如果您的 IProgressMonitor 接口(interface)出现错误,请注意,它已从 org.eclipse.core.runtime 移至 org.eclipse.equinox.common,因此请记住使用正确的依赖项。也偶然发现了这个小问题。我希望这有帮助!

关于java - 是否可以使用 DaisyDiff 保留输入标记?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48262713/

相关文章:

java - 在这种情况下,Jackson 在使用 ObjectMapper.readTree 反序列化 JSON 时会创建 ShortNode?

具有 2 个变量的 Javascript 计算

javascript - 隐形谷歌 Recaptcha 和 ajax 形式

python - 快速找出两个大文本文件之间的差异

linux - diff 文件只比较每行的前 n 个字符

java - 排序键是 HashMap 中的日期条目

java - 如何从 Firebase Firestore 获取数据?

java - 如何使用spring mvc通过gridfs下载存储在mongodb中的文件

html - 如何修复图片水平翻转?

merge - wiki 如何处理多个同时编辑?