试图在Java中实现HTML文件比较,但最终在saxon开始元素中出现空指针异常

试图在Java中实现HTML文件比较,但最终在saxon开始元素中出现空指针异常,java,saxon,Java,Saxon,我正在尝试实现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.Html

我正在尝试实现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());
    }
公共类DaizyDiff{
静态字符串html1=“Hello”;
静态字符串html2=“Bye”;
公共静态void main(字符串args[])引发TransformerConfiguration异常、IOException、SAXException{
最终StringWriter finalResult=新StringWriter();
最终的SAXSTransformerFactory tf=(SAXSTransformerFactory)TransformerFactory.newInstance();
最终TransformerHandler结果=tf.newTransformerHandler();
result.getTransformer().setOutputProperty(OutputKeys.OMIT_XML_声明,“yes”);
result.getTransformer().setOutputProperty(OutputKeys.INDENT,“yes”);
result.getTransformer().setOutputProperty(OutputKeys.METHOD,“html”);
result.getTransformer().setOutputProperty(OutputKeys.ENCODING,“UTF-8”);
result.setResult(新的StreamResult(finalResult));
最终ContentHandler后处理=结果;
最终语言环境=Locale.getDefault();
最终字符串前缀=“diff”;
最终NekoHtmlParser cleaner=新的NekoHtmlParser();
最终输入源oldSource=新输入源(新StringReader(html1));
final InputSource newSource=新的InputSource(新的StringReader(html2));
final DomTreeBuilder oldHandler=新的DomTreeBuilder();
parse(oldSource,oldHandler);
final TextNodeComparator leftComparator=新的TextNodeComparator(oldHandler,locale);
final DomTreeBuilder newHandler=new DomTreeBuilder();
parse(newSource,newHandler);
final TextNodeComparator rightComparator=新的TextNodeComparator(newHandler,locale);
最终HTMLSAXDIFOUTPUT输出=新HTMLSAXDIFOUTPUT(后处理,前缀);
最终HTMLDiffer=新HTMLDiffer(输出);
diff.diff(左比较器、右比较器);
System.out.println(finalResult.toString());
System.out.println(finalResult.toString());
}

您使用的是哪个Saxon版本?在当前版本(9.9)中,
ReceivingContentHandler.startElement()方法不在第279行附近,这表明您使用的是一个相当旧的版本

然而,DaisyDiff调用Saxon的
ContentHandler
的方式可能与它期望的调用方式不同。不幸的是,XML解析器对
ContentHandler
的调用顺序取决于XML解析器的配置方式,以及典型的
ContentHandler
实现(如Saxon)需要以特定方式配置XML解析器(或
ContentHandler
事件的其他发送方)

原因是典型Saxon用例的
ContentHandler
是一个性能非常关键的接口,
startElement()
方法在每次调用中对提供的参数进行完全验证会产生很大的开销;它必须信任调用者

除非您准备深入研究DaisyDiff和Saxon源代码,以找出不匹配的原因(可能还需要编写一个过滤器来解决它们之间的不匹配问题),否则您最好将DaisyDiff输出输入到词法XML中,并重新分析XML以将其发送到Saxon


进一步看,实际上您只是将
TransformerHandler
用作XML序列化程序。DaisyDiff(查看GitHub上的源代码)正在对其编写的TransformerHandler/ContentHandler进行各种假设(例如,它似乎没有对
startDocument()进行任何调用)
endDocument()
)。我的猜测是,它可能只在JDK附带的
TransformerHandler
的实现上进行过测试,并且它可能与
TransformerHandler
配合使用。我认为您在这里做的并不是真正需要Saxon的任何事情,我认为您之所以选择它,是因为它恰好在类路径上,最好的方法可能是确保对
TransformerFactory.newInstance()
的调用选择JDK transformer工厂而不是Saxon。因此,请使用
newInstance()
版本,该版本要求工厂类名作为其第一个参数,提供
“com.sun.org.apache.xalan.internal.processor.TransformerFactoryImpl"

你能分享你的确切代码吗?你提供的例外在不知道其背后的代码的情况下是无用的。我用我的确切代码编辑了我的问题。你看过这个例子吗?这似乎与你以前问的问题完全相同。我知道它没有真正的答案,但问完全相同的问题没有意义上两次。在处有一个公认的问题答案-,但这并不是问题的真正解决方案。该答案要求您生成堆栈跟踪以帮助诊断。以后请继续原来的问题,而不是再次问相同的问题。嗨,Michael Kay。谢谢您的时间。我对这个问题不熟悉,不知道如何roceed进一步。您是否可以帮助我修改代码的位置和内容。这将对我非常有帮助。谢谢。不,对不起,我可以尝试回答特定的问题,但我不能为您提供Java编程方面的私人培训课程。