1

我正在使用 XSLT 2.0 将 XML 文件转换为 XHTML。我正在使用 saxon9 处理器进行转换。转换时,我收到一个错误,例如

java.io.FileNotFoundException: c:\test\book.dtd(系统找不到指定的文件)。

它正在寻找 DTD,因为 XML 具有带有 PUBLIC id 的 DOCTYPE 声明。

我正在寻找解决此错误的解决方案,但我无法做到这一点。我尝试使用resolver.jar。

我已经下载了resolver.jar并放置在saxon.jar所在的同一位置,并尝试了以下命令行。

java -cp c:/saxon9/saxon9.jar;c:saxon9/resolver.jar; net.sf.saxon.Transform -x:org.apache.xml.resolver.tools.ResolvingXMLReader -t -s:c:/test/sample2.xml -xsl:c:/test/body.xsl >c:/test/out /output.html

我收到相同的错误消息。

我推荐了几个网站来使用 resolver.jar,但我不清楚说明并且没有获得所需的输出。

我找到了http://sourceforge.net/apps/mediawiki/saxon/index.php?title=XML_Catalogs。这是使用 resolver.jar 省略 DOCTYPE 声明的正确解决方案吗?如果这么好心地帮助如何使用它,或者有没有其他可以使用的方法?

我的 XML 文件看起来像

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//ES//DTD book DTD version 5.3.0//EN//XML" "book.dtd" [<!  ENTITY fx1 SYSTEM "fx1" NDATA IMAGE>]>
<chapter>
<info>
<ce:link locator="fx1"/>…

我已经创建了如下所示的 catalog.xml 文件并存储在同一位置。

<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="-//ES//DTD book DTD version 5.3.0//EN//XML" uri="book.dtd"/>
</catalog>

我还在环境变量中定义了类路径,如下所示:

c:\saxon9\saxon9.jar;c:\saxon\resolver.jarUsed the following command line for conversion(referred http://sourceforge.net/apps/mediawiki/saxon/index.php?title=XML_Catalogs)

但是我仍然面临同样的问题,我找不到确切的问题在哪里,还有什么需要做的?

C:\>java -cp c:\saxon9\saxon9.jar;c:\saxon9\resolver.jar -Dxml.catalog.files=c:\saxon9\catalog.xml net.sf.saxon.Transform -r:org.apache.xml.resolver.tools.CatalogResolver  -x:org.apache.xml.resolver.tools.ResolvingXMLReader -y:org.apache.xml.resolver.tools.ResolvingXMLReader -xsl:c:\test\body1.xsl -s:c:\test\Main.xml -o:c:\test\output.html

但收到以下错误

Error java.io.FileNotFoundException: c:\test\book.dtd (The system cannot find the file specified)
Transformation failed: Run-time errors were reported

非常感谢及时的帮助,因为这是非常紧急的......

4

3 回答 3

2

xmllint 工具对我有用。

xmllint --dropdtd -o file.xml file.xml

正如 Thomas 提到的,您可以将结果通过管道传输到 saxonb。

xmllint --dropdtd file.xml | saxonb-xslt -s:- -xsl:stylesheet.xsl
于 2016-10-24T07:36:50.463 回答
0

如果您使用的是 Linux 系统,您可以去除 DOCTYPE 声明,例如使用 sed,并将结果通过管道传输到 Saxon,例如:

sed '/<!DOCTYPE/d' in.xml | saxonb-xslt -s:- -xsl:stylesheet.xsl
于 2012-12-26T07:49:53.230 回答
0

很大程度上取决于输入 XML 文件中 doctype 声明的形式。由于 Saxon 正在寻找“C:\test\book.dtd”,因此听起来好像存在一个外部标识符。所以你有类似其中之一的东西:

1. <!DOCTYPE book PUBLIC "some-public-id" "c:\test\book.dtd">

2. <!DOCTYPE book SYSTEM "c:\test\book.dtd">

基本问题是系统标识符部分(“c:\test\book.dtd”)是硬默认值。除非您使用目录机制指向 DTD 的其他位置,否则它将始终查找它。(这是我们必须忍受的 XML 规范中的一个缺陷。)

首要任务是您是否有源 XML 格式的 DTD。如果您不这样做并且无法获得一个,那么您唯一的选择是预处理源 XML 并删除 doctype 声明的整个外部标识符部分(即上述两种形式中的任何一种)。删除整个 doctype 声明也是可以的,只要它没有内部子集(一对 '[' 和 ']' 分隔符之间的其他声明。)

如果您有 DTD,您可以将副本放在 c:\test\book.dtd。如果您不想这样做,则必须使用目录机制将 Saxon(及其解析器)指向所需的位置。仅仅将resolver.jar 放在您的类路径中是不够的。你还需要给它一些可以使用的东西!

特别是,您需要给它一个目录文件(通过 xml.catalog.files 环境变量 - 请注意文档中示例的命令行);并且您需要在目录中输入 XML 格式的 DTD 条目。这应该将系统标识符“c:\test\book.dtd”(和/或公共标识符,如果源 XML 在 doctype 声明中有一个)映射到文件系统中放置 DTD 的位置。

于 2012-12-26T16:02:59.977 回答