本文介绍了使用 XSLT 即 XML Transformer 时防止 DTD 下载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须在 Java 中处理具有 DTD 和 XSLT 的 XML 文件.确实需要 DTD,因为它包含我使用的实体的定义.(旁白:是的,将实体用于可以使用 unicode 的东西是一个坏主意;-)

I have to process XML files that have a DTD with a XSLT in Java. The DTD is really needed because it contains the definitions of entities I use. (aside: yes, using entities for stuff that could use unicode is a bad idea ;-)

当我运行转换时,它每次都从外部源下载 DTD.我希望它使用 XML 目录来缓存 DTD,所以我给了 TransformerFactory 一个 CatalogResolver 作为 URIResolver:

When I run the transformation it downloads the DTD from the external source every time. I want it to use a XML catalog to cache the DTDs so I gave the TransformerFactory a CatalogResolver as URIResolver:

URIResolver cr = new CatalogResolver();
tf = TransformerFactory.newInstance();
tf.setURIResolver(cr);
Transformer t = tf.newTransformer(xsltSrc);
t.setURIResolver(cr);
Result res = new SAXResult(myDefaultHandler());
t.transform(xmlSrc, res);

但是当我运行转换时,它仍然通过网络下载 DTD.(使用 Xalan 和 Xerces 作为 Java5 的一部分或独立使用,或者使用 Saxon 和 Xerces.)

But when I run the transformation it still downloads the DTDs over the network. (Using Xalan and Xerces either as part of Java5 or standalone or using Saxon and Xerces.)

强制转换仅使用 DTD 的本地副本需要什么?

What does it take to force the transformation to only use the local copy of the DTDs?

推荐答案

(我在这里回答我自己的问题是为了节省下一次我或其他任何人,我需要修补的日子来找到答案.)

(I'm answering my own question here to save me the next time, or anyone else, the days of tinkering I needed to find the answer.)

真正需要改变 DTD 解析方式的是 EntityResolver.不幸的是,无法设置 EntityResolver 以供 Transformer 使用.因此,您必须首先创建一个 XMLReader,并将 CatalogResolver 作为它的 EntityResolver:

What it really needs to change the way DTDs are resolved is an EntityResolver. Unfortunately it is not possible to set the EntityResolver to be used by the Transformer. So you have to create an XMLReader first with the CatalogResolver as its EntityResolver:

SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
XMLReader r = spf.newSAXParser().getXMLReader();
EntityResolver er = new CatalogResolver();
r.setEntityResolver(er);

并将其用于Transformer:

SAXSource s = new SAXSource(r, xmlSrc);
Result res = new SAXResult(myDefaultHandler());
transformer.transform(s, res);

这篇关于使用 XSLT 即 XML Transformer 时防止 DTD 下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 09:21