Java、xml、XSLT:防止DTD验证
我使用Java(6)XMLAPI对来自web的html文档应用xslt转换。此文档是格式良好的xhtml,因此包含有效的DTD规范(Java、xml、XSLT:防止DTD验证,java,xml,xslt,Java,Xml,Xslt,我使用Java(6)XMLAPI对来自web的html文档应用xslt转换。此文档是格式良好的xhtml,因此包含有效的DTD规范()。 现在出现了一个问题:Uppon转换XSLT处理器试图下载DTD,而w3服务器通过HTTP 503错误(由w3引起)拒绝了这一点 如何防止XSLT处理器下载dtd?我不需要验证输入文档。 资料来源是: import javax.xml.transform.Source; import javax.xml.transform.Transformer; import
)。
现在出现了一个问题:Uppon转换XSLT处理器试图下载DTD,而w3服务器通过HTTP 503错误(由w3引起)拒绝了这一点
如何防止XSLT处理器下载dtd?我不需要验证输入文档。
资料来源是:
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
--
String xslt=“”+
""+
" "+
" "+
" "+
" "+
" "+
"";
试一试{
Source xmlSource=新的流源(“http://de.wikipedia.org/wiki/Right_Livelihood_Award");
Source xsltSource=newstreamsource(newstringreader(xslt));
TransformerFactory ft=TransformerFactory.newInstance();
变压器变压器=ft.newTransformer(xsltSource);
trans.transform(xmlSource,newstreamresult(System.out));
}
捕获(例外e){
e、 printStackTrace();
}
我在此阅读了以下问题,但它们都使用了另一个XML Api:
谢谢 您需要使用javax.xml.parsers.DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource src = new InputSource("http://de.wikipedia.org/wiki/Right_Livelihood_Award")
Document xmlDocument = builder.parse(src.getByteStream());
DOMSource source = new DOMSource(xmlDocument);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer(xsltSource);
transformer.transform(source, new StreamResult(System.out));
我最近在使用JAXB解组XML时遇到了这个问题。答案是从XmlReader和InputSource创建SAXSource,然后将其传递给JAXB解组器的unmarshal()方法。为了避免加载外部DTD,我在XmlReader上设置了一个自定义EntityResolver
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xmlr = sp.getXMLReader();
xmlr.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String pid, String sid) throws SAXException {
if (sid.equals("your remote dtd url here"))
return new InputSource(new StringReader("actual contents of remote dtd"));
throw new SAXException("unable to resolve remote entity, sid = " + sid);
} } );
SAXSource ss = new SAXSource(xmlr, myInputSource);
如前所述,如果此自定义实体解析程序被要求解析您希望它解析的实体以外的实体,则它将引发异常。如果您只想继续加载远程实体,请删除“throws”行。尝试在DocumentBuilderFactory中设置功能:
URL url = new URL(urlString);
InputStream is = url.openStream();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder db;
db = dbf.newDocumentBuilder();
Document result = db.parse(is);
现在,当调用document函数分析外部XHTML页面时,我在XSLT(2)中遇到了同样的问题。如果使用
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
您可以尝试使用FLOWING代码禁用dtd验证:
dbf.setValidating(false);
前面的答案让我找到了一个解决方案,但对我来说并不明显,因此这里有一个完整的答案:
private void convert(InputStream xsltInputStream, InputStream srcInputStream, OutputStream destOutputStream) throws SAXException, ParserConfigurationException,
TransformerFactoryConfigurationError, TransformerException, IOException {
//create a parser with a fake entity resolver to disable DTD download and validation
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
xmlReader.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String pid, String sid) throws SAXException {
return new InputSource(new ByteArrayInputStream(new byte[] {}));
}
});
//create the transformer
Source xsltSource = new StreamSource(xsltInputStream);
Transformer transformer = TransformerFactory.newInstance().newTransformer(xsltSource);
//create the source for the XML document which uses the reader with fake entity resolver
Source xmlSource = new SAXSource(xmlReader, new InputSource(srcInputStream));
transformer.transform(xmlSource, new StreamResult(destOutputStream));
}
感谢您的回答,但这段代码实际上抛出了相同的异常:
java.io.IOException:Server返回了URL的HTTP响应代码:503:http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
您必须更改src.getByTestStream()
到第5行中的src
以使其工作,但仍然存在相同的异常。这不会改变任何内容。您可以在从流源转换期间解析文档,当然也可以在转换为DOMSource之前解析文档,但任何一种方式都会出现DTD缺失异常。所以这个“解决方案”解决不了任何问题,只是误导。克里斯的答案是完全一样的。以防万一,有人也有同样的问题:这导致了正确的方向(这就是我接受答案的原因)。如果不想返回DTD,也可以返回一个空DTD。请修复大小写:“XmlReader”应为“XmlReader”
private void convert(InputStream xsltInputStream, InputStream srcInputStream, OutputStream destOutputStream) throws SAXException, ParserConfigurationException,
TransformerFactoryConfigurationError, TransformerException, IOException {
//create a parser with a fake entity resolver to disable DTD download and validation
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
xmlReader.setEntityResolver(new EntityResolver() {
public InputSource resolveEntity(String pid, String sid) throws SAXException {
return new InputSource(new ByteArrayInputStream(new byte[] {}));
}
});
//create the transformer
Source xsltSource = new StreamSource(xsltInputStream);
Transformer transformer = TransformerFactory.newInstance().newTransformer(xsltSource);
//create the source for the XML document which uses the reader with fake entity resolver
Source xmlSource = new SAXSource(xmlReader, new InputSource(srcInputStream));
transformer.transform(xmlSource, new StreamResult(destOutputStream));
}