gpt4 book ai didi

java - TransformerFactory - 避免网络查找来验证 DTD

转载 作者:数据小太阳 更新时间:2023-10-29 02:24:07 30 4
gpt4 key购买 nike

我需要为 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 在本地可用,但我不知道如何指示转换器查看本地文件,而不是尝试进行网络查找。

据我所知,转换器需要这些文档才能正确进行转换。

有关信息,我正在将 MusicXML 文档从 Partwise 转换为 Timewise。

您可能已经猜到,XSLT 不是我的强项(远非如此)。

我是否需要修改 XSLT 文件以引用本地文件,或者可以采用不同的方式来完成吗?


除了下面的评论,这里是 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">

我假设这些文件也将依次导入。

最佳答案

好的,这是适合我的答案。

第 1 步:加载原始文档,关闭工厂内的验证和 dtd 加载。

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// stop the network loading of DTD files
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
DocumentBuilder docbuilder = factory.newDocumentBuilder();
Document doc = docbuilder.parse(new FileInputStream(m_strFilePath));

第二步:现在我已经在内存中获得了文档......并且在检测到我需要转换它之后 -

TransformerFactory transformfactory = TransformerFactory.newInstance();
Templates xsl = transformfactory.newTemplates(new StreamSource(new FileInputStream((String)m_XslFile)));
Transformer transformer = xsl.newTransformer();
Document newdoc = docbuilder.newDocument();
Result XmlResult = new DOMResult(newdoc);
// now transform
transformer.transform(
new DOMSource(doc.getDocumentElement()),
XmlResult);

我需要这样做,因为之后我还有进一步的处理,不希望输出到文件和重新加载的开销。

小解释:

诀窍是使用已关闭所有验证功能的原始 DOM 对象。你可以在这里看到这个:

transformer.transform(
new DOMSource(doc.getDocumentElement()), // <<-----
XmlResult);

这已经在关闭网络访问的情况下进行了测试。所以我知道不再有网络查找。

但是,如果 DTD、MOD 等在本地可用,那么根据建议,使用 EntityResolver 就是答案。这将再次应用于原始 docbuilder 对象。

我现在有一个转换后的文档存储在 newdoc 中,可以使用了。

我希望这对其他人有帮助。

关于java - TransformerFactory - 避免网络查找来验证 DTD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18966597/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com