java - 尝试在 Java 中实现 HTML 文件比较,但在 saxon 开始元素中出现 NULL 指针异常
问题描述
我正在尝试实现 java 程序来比较两个 HTML 文件。我在互联网上浏览了很多资源,但对我来说一切都止于一处。那就是我低于异常
Exception in thread "main" java.lang.NullPointerException
at net.sf.saxon.event.ReceivingContentHandler.startElement(ReceivingContentHandler.java:279)
at org.outerj.daisy.diff.html.HtmlSaxDiffOutput.generateOutput(Unknown Source)
at org.outerj.daisy.diff.html.HTMLDiffer.diff(Unknown Source)
at com.interac.api.emt.noti.DaizyDiff.main(DaizyDiff.java:63)
我的完整代码:
public class DaizyDiff {
static String html1 = "<html class='foobar'>Hello</html>";
static String html2 = "<html>Bye</html>";
public static void main(String args[]) throws TransformerConfigurationException, IOException, SAXException {
final StringWriter finalResult = new StringWriter();
final SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory.newInstance();
final 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));
final ContentHandler postProcess = result;
final Locale locale = Locale.getDefault();
final String prefix = "diff";
final NekoHtmlParser cleaner = new NekoHtmlParser();
final InputSource oldSource = new InputSource(new StringReader(html1));
final InputSource newSource = new InputSource(new StringReader(html2));
final DomTreeBuilder oldHandler = new DomTreeBuilder();
cleaner.parse(oldSource, oldHandler);
final TextNodeComparator leftComparator = new TextNodeComparator(oldHandler, locale);
final DomTreeBuilder newHandler = new DomTreeBuilder();
cleaner.parse(newSource, newHandler);
final TextNodeComparator rightComparator = new TextNodeComparator(newHandler, locale);
final HtmlSaxDiffOutput output = new HtmlSaxDiffOutput(postProcess, prefix);
final HTMLDiffer differ = new HTMLDiffer(output);
differ.diff(leftComparator, rightComparator);
System.out.println(finalResult.toString());
System.out.println(finalResult.toString());
}
解决方案
您使用的是哪个撒克逊版本?在当前版本 (9.9) 中,该方法ReceivingContentHandler.startElement()
与第 279 行相去甚远,这表明您使用的是相当旧的版本。
然而,很有可能 DaisyDiff 并没有ContentHandler
以它期望的方式调用 Saxon's。不幸的是,XML 解析器对 a 的调用顺序ContentHandler
取决于 XML 解析器的配置方式,而典型的ContentHandler
实现(如 Saxon 的)需要ContentHandler
以特定方式配置 XML 解析器(或其他事件发送方)。
这样做的原因是,ContentHandler
典型的 Saxon 用例是一个对性能非常关键的接口,并且该startElement()
方法在每次调用时对提供的参数进行全面验证将是一个巨大的开销;它必须信任调用者。
除非您准备好深入研究 DaisyDiff 和 Saxon 源代码以找出不匹配的原因(并且可能编写一个过滤器来坐在它们之间并解决不匹配问题),否则您最好将 DaisyDiff 输出输入到词法 XML 中,并重新解析 XML 以将其发送给 Saxon。
进一步看,您实际上TransformerHandler
只是将其用作 XML 序列化程序。DaisyDiff(查看 GitHub 上的源代码)正在对其写入的 TransformerHandler/ContentHandler 做出各种假设(例如,它似乎没有对startDocument()
or进行任何调用endDocument()
)。我的猜测是,它可能只TransformerHandler
在 JDK 附带的实现上进行了测试,它可能很好地与TransformerHandler
. TransformerFactory.newInstance()
我认为您在这里没有做任何真正需要 Saxon 的事情,我认为您只是因为它恰好在类路径上而选择它,而您最好的前进方式可能是确保您的电话接听JDK 变压器工厂而不是撒克逊。所以使用的版本newInstance()
它需要一个工厂类名称作为它的第一个参数,提供"com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl"
.
推荐阅读
- django - 在原始查询集中使用 ILIKE 不区分大小写以检查其中一个字段是否以预定义字母开头
- tensorflow - 使用估计作为特征的多任务学习
- c# - AutoMapper 使用方法从源映射值
- android - 如何为 2019 年 1 月后更新的 AutocompleteSupportFragment api 设置过滤器
- javascript - 文件名和 img 显示问题
- python-2.7 - 使用 :'s 格式化 MAC 地址字符串
- php - 413 使用 laravel 和 amazon S3 请求实体太大
- android - 广播接收器未捕获传入消息
- python - 使用opencv跟踪皮带上的土豆,最好的选择?
- r - 如何使用嵌套循环?