如何在将使用getResourceAsStream()加载的XML文件中包含DTD?

时间:2008-11-26 15:22:04

标签: java xml xerces

我有一个xml文件('videofaq.xml'),它使用以下DOCTYPE定义DTD

<!DOCTYPE video-faq SYSTEM "videofaq.dtd">

我在Servlet初始化时使用以下命令从类路径(实际上是从JAR)加载文件:

getClass().getResourceAsStream("videofaq.xml")

找到了正确的XML,但是对于同一个包中的DTD,Xerces给了我一个FileNotFoundException,并显示了Tomcat启动脚本的路径,并在末尾添加了“videofaq.dtd”。如果有的话,我可以将哪些提示传递给Xerces以使其正确加载DTD?

4 个答案:

答案 0 :(得分:1)

当你这样做时

getClass().getResourceAsStream("videofaq.xml")

这不是你要调用的xerces,因此,当你将流提供给xerces时,它无法知道文件的加载位置。它从应用程序根路径(您已描述过)中加载它。

一个简单的解决方案是将xml文件中的整个路径指定为dtd。

此外,xerces似乎尝试了多个地方。所以你应该看一下语法缓存机制或实体解析器(我认为按顺序使用)。

Xerces语法文档:http://xerces.apache.org/xerces2-j/faq-grammars.html

Xerces功能use-entity-resolver2:http://xerces.apache.org/xerces2-j/features.html

答案 1 :(得分:1)

自定义EntityResolver可以工作,但您可以通过设置SystemID来允许处理器“找到”相对路径来避免创建自定义类。

http://www.onjava.com/pub/a/onjava/excerpt/java_xslt_ch5/index.html?page=5

  

通过提供系统标识符作为   您是StreamSource的参数   告诉XSLT处理器在哪里   寻找commonFooter.xslt。没有   这个参数,你可能会遇到一个   处理器无法出错   解析此URI。简单的解决方法是   将setSystemId()方法称为   如下:

// construct a Source that reads from an InputStream
Source mySrc = new StreamSource(anInputStream);
// specify a system ID (a String) so the 
// Source can resolve relative URLs
// that are encountered in XSLT stylesheets
mySrc.setSystemId(aSystemId);

答案 2 :(得分:0)

使用SAX时,您可以提供自己的EntityResolver,然后以您想要的任何方式加载资源。

答案 3 :(得分:0)

通常,在为XML解析器指定输入时,尝试使用带有URL的方法重载(通常作为带有参数名称的字符串,如“systemId”)。这允许解析器为您解析相对引用,并提供更好的错误消息。

因此,在您的情况下,使用videofaq.xml在相同的包中找到DTD,并将String getClass().getResource("videofaq.xml")的结果传递给XML解析器。