【发布时间】:2013-09-23 18:47:42
【问题描述】:
我需要为 XML 文档的离线转换编程。 在使用以下内容加载原始 XML 文件时,我已经能够停止 DTD 网络查找:
DocumentBuilderFactory factory;
factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
factory.setFeature("http://xml.org/sax/features/namespaces", false);
factory.setFeature("http://xml.org/sax/features/validation", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
// open up the xml document
docbuilder = factory.newDocumentBuilder();
doc = docbuilder.parse(new FileInputStream(m_strFilePath));
但是,我无法将其应用于 TransformerFactory 对象。 DTD 在本地可用,但我不知道如何指示转换器查看本地文件,而不是尝试进行网络查找。
据我所知,transformer 需要这些文件才能正确进行转换。
有关信息,我正在将 MusicXML 文档从 Partwise 转换为 Timewise。
您可能已经猜到,XSLT 不是我的强项(远非如此)。
我是否需要修改 XSLT 文件以引用本地文件,或者可以以不同的方式完成吗?
除了下面的 cmets,这里是 xsl 文件的摘录。这是我看到的唯一一个引用外部文件的地方:
<!--
XML output, with a DOCTYPE refering the timewise DTD.
Here we use the full Internet URL.
-->
<xsl:output method="xml" indent="yes" encoding="UTF-8"
omit-xml-declaration="no" standalone="no"
doctype-system="http://www.musicxml.org/dtds/timewise.dtd"
doctype-public="-//Recordare//DTD MusicXML 2.0 Timewise//EN" />
上述技术是否也适用于此?
DTD 文件包含对许多 MOD 文件的引用,如下所示:
<!ENTITY % layout PUBLIC
"-//Recordare//ELEMENTS MusicXML 2.0 Layout//EN"
"layout.mod">
我想这些文件也会依次导入。
【问题讨论】:
-
您可以尝试将 docs.oracle.com/javase/7/docs/api/javax/xml/transform/… 设置为加载本地 DTD 的解析器实现。
-
感谢@MartinHonnen,我查看了您提供的链接,发现它适用于导入和包含。那么 xsl 没有任何明确的包含。我将在下面摘录来说明我的意思。
-
“我想这些文件也会被依次导入”——你验证了吗?据我了解,
<xsl:output>不会导致样式表处理器实际加载 DTD,它只会影响在将其序列化为 XML 时添加到输出树的<!DOCTYPE>。 -
坦率地说@IanRoberts,我不确定。我所知道的是,如果我断开网络连接,它会抛出一个异常,说它无法连接到“www.musicxml.org”。当我尝试实现 URIResolver 时,它甚至没有被调用。我在这里有点不知所措!