1

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

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

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

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

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

4

4 回答 4

1

当你这样做

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

您调用的不是 xerces,因此,当您将流提供给 xerces 时,它不知道文件是从哪里加载的。它从应用程序根路径(您已描述)加载它。

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

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

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

Xerces 功能使用实体解析器2:http: //xerces.apache.org/xerces2-j/features.html

于 2008-11-26T16:02:51.823 回答
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);
于 2008-11-28T14:11:13.363 回答
0

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

于 2008-11-26T16:04:07.767 回答
0

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

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

于 2008-11-26T16:19:03.633 回答