我正在通过Ant的XSLT任务运行一些XSL转换。我使用Saxon 9HE作为处理引擎。我有一种情况,输入XML文件都使用相同的DTD,但声明它在不同的地方。有些人声明它在当前目录中,有些在文件夹中,而其他人引用了URL。这是Ant脚本:
<?xml version="1.0" encoding="UTF-8"?>
<project name="PubXML2EHeader" default="transform">
<property name="data.dir.input" value="./InputXML"/>
<property name="data.dir.output" value="./converted-xml"/>
<property name="xslt.processor.location" value="D:\\saxon9he.jar"/>
<property name="xslt.processor.factory" value="net.sf.saxon.TransformerFactoryImpl"/>
<path id="saxon9.classpath" location="${xslt.processor.location}"/>
<target name="clean">
<delete dir="${data.dir.output}" includes="*.xml" failonerror="no"/>
</target>
<target name="transform" depends="clean">
<xslt destdir="${data.dir.output}"
extension=".xml"
failOnTransformationError="false"
processor="trax"
style="Transform.xsl"
useImplicitFileset="false"
classpathref="saxon9.classpath"
>
<outputproperty name="method" value="xml"/>
<outputproperty name="indent" value="yes"/>
<fileset dir="${data.dir.input}" includes="**/*.xml" excludes="Transform.xml"/>
<factory name="${xslt.processor.factory}"/>
</xslt>
</target>
</project>
当我运行这个Ant脚本时,我得到这样的错误:
[xslt]:致命错误! XML解析器处理报告的I / O错误 文件:/ d:/annurev.biophys.093008.131228.xml: http://www.atypon.com/DTD/nlm-dtd/archivearticle.dtd原因: java.io.FileNotFoundException: http://www.atypon.com/DTD/nlm-dtd/archivearticle.dtd
我认为这是由于Saxon无法访问DTD(在这种情况下实际上是防火墙问题)。我不认为我关心验证输入,这是我认为这里发生的事情,我想跳过它。是否有一个属性可以添加到XSLT Ant任务中以阻止Saxon尝试读取DTD?
答案 0 :(得分:6)
您正在混淆“阅读DTD”并进行验证。 XSLT处理器将始终要求解析器读取文档的外部DTD,无论它是否正在验证。这是因为DTD不仅仅用于验证;它也用于扩展实体引用。
解决此问题的常用方法是将DTD引用重定向到可以访问的某个副本,通常使用目录。这涉及在底层XML解析器上设置EntityResolver。
网上有很多关于如何使用Saxon设置目录解析器的信息,通常来自命令行:例如参见:http://www.sagehill.net/docbookxsl/UseCatalog.html
建议通常是设置-x,-y和-r选项,但实际上只有-x是相关的,如果您只需要在源文档中重定向DTD引用(-y影响样式表,-r影响document()函数)。在Ant中,相当于设置-x选项是使用factory元素的属性child来设置配置属性<attribute name="http://saxon.sf.net/feature/sourceParserClass" value="org.apache.xml.resolver.tools.ResolvingXMLReader"/>
。
这仍然留下我发现棘手的部分,这实际上是在创建目录文件。