我有一个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?
答案 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解析器。