Java 指定DocumentBuilders用于XML解析的DTD?

Java 指定DocumentBuilders用于XML解析的DTD?,java,xml,sax,xerces,docbook,Java,Xml,Sax,Xerces,Docbook,我目前正在使用Java1.6编写一个工具,它汇集了许多XML文件。所有文件都验证为DocBook 4.5 DTD(我使用xmllint检查了这一点,并将DocBook 4.5 DTD指定为--dtdvalid参数),但并非所有文件都包含DOCTYPE声明 我将每个XML文件加载到DOM中,以执行所需的操作,如下所示: private Document fileToDocument( File input ) throws ParserConfigurationException, IOExcep

我目前正在使用Java1.6编写一个工具,它汇集了许多XML文件。所有文件都验证为DocBook 4.5 DTD(我使用xmllint检查了这一点,并将DocBook 4.5 DTD指定为--dtdvalid参数),但并非所有文件都包含DOCTYPE声明

我将每个XML文件加载到DOM中,以执行所需的操作,如下所示:

private Document fileToDocument( File input ) throws ParserConfigurationException, IOException, SAXException {

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    factory.setNamespaceAware(true);
    factory.setIgnoringElementContentWhitespace(false);
    factory.setIgnoringComments(false);
    factory.setValidating(false);
    factory.setExpandEntityReferences(false);

    DocumentBuilder builder = factory.newDocumentBuilder();
    return builder.parse( input );

}
在大多数情况下,这工作得相当好,我可以使用返回的对象来导航树并执行所需的操作,然后将文档写回。我遇到的问题是以下文件:

  • 不包括DOCTYPE声明,以及
  • 包括DTD中定义的实体(例如—/-)
在这种情况下,builder.parse(…)调用引发异常,并显示以下消息:

[Fatal Error] :5:15: The entity "mdash" was referenced, but not declared.
很公平,它没有被宣布。在本例中,我理想的做法是将DocumentBuilderFactory设置为始终使用DocBook 4.5 DTD,而不管文件中是否指定了DTD

我确实尝试过使用Docbook4.5模式进行验证,但发现这会产生许多与XML无关的错误。至少对于DocBook规范的这个版本来说,这个模式在功能上可能与DTD不同

我可以想到的另一个选项是读取文件,尝试检测是否设置了doctype,然后在将XML解析到DOM之前,如果没有找到doctype,则设置一个


因此,我的问题是,有没有一种我没有见过的更聪明的方法,可以告诉解析器使用特定的DTD,或者确保在实体未解析的情况下(不仅仅是&emdash;示例,还有XML中的任何实体,它们都有大量潜力)解析仍能继续进行

能否使用EntityResolve2并实施帮助

。。。此方法也可用于没有DOCTYPE声明的文档。当遇到根元素,但未看到DOCTYPE声明时,将调用此方法。如果它为外部子集返回一个值,则该根元素被声明为根元素,从而产生在文档序言末尾拼接DOCTYPE声明的效果,否则该文档将无效


谢谢,我不知道EntityResolver 2接口(只有EntityResolver)。一旦我重载了建议的方法,并为其他方法提供了默认处理,我现在遇到以下错误:[致命错误]docbookx.dtd:101:9:递归实体引用“%dbnotn”。(引用路径:%dbnotn->%dbnotn->%dbnotn)基于此,DTD现在似乎至少正在应用,但存在其他问题:)。