省略DOCTYPE声明

时间:2012-12-26 06:49:23

标签: xml xslt xslt-2.0 saxon

我正在使用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

及时帮助非常感谢,因为这非常紧迫......

3 个答案:

答案 0 :(得分:2)

xmllint工具对我有用。

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

正如托马斯所说,你可以将结果传递给萨克森。

xmllint --dropdtd file.xml | saxonb-xslt -s:- -xsl:stylesheet.xsl

答案 1 :(得分:0)

如果您使用的是Linux系统,则可以删除DOCTYPE声明,例如:使用sed,并将结果传递给Saxon,如:

sed '/<!DOCTYPE/d' in.xml | saxonb-xslt -s:- -xsl:stylesheet.xsl

答案 2 :(得分: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环境变量 - 请注意documentation中示例的命令行);并且您需要在目录中输入输入XML格式的DTD。这应该将系统标识符'c:\ test \ book.dtd'(和/或公共标识符,如果源XML在doctype声明中有一个)映射到文件系统中放置DTD的位置。