Java, xml, XSLT: Prevent DTD-Validation

java, xml, xslt

Solution

I recently had this issue while unmarshalling XML using JAXB. The answer was to create a SAXSource from an XmlReader and InputSource, then pass that to the JAXB UnMarshaller's unmarshal() method. To avoid loading the external DTD, I set a custom EntityResolver on the XmlReader.

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);

As written, this custom entity resolver will throw an exception if it's ever asked to resolve an entity OTHER than the one you want it to resolve. If you just want it to go ahead and load the remote entity, remove the "throws" line.

Problem

I use the Java (6) XML-Api to apply a xslt transformation on a html-document from the web. This document is wellformed xhtml and so contains a valid DTD-Spec (`<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">`). Now a problem occurs: Uppon transformation the XSLT-Processor tries to download the DTD and the w3-server denies this by a HTTP 503 error (due to Bandwith Limitation by w3). How can I prevent the XSLT-Processor from downloading the dtd? I dont need my input-document validated. Source is: ``` 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 = "<?xml version=\"1.0\"?>"+ "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"+ " <xsl:output method=\"text\" />"+ " <xsl:template match=\"//html/body//div[@id='bodyContent']/p[1]\"> "+ " <xsl:value-of select=\".\" />"+ " </xsl:template>"+ " <xsl:template match=\"text()\" />"+ "</xsl:stylesheet>"; try { Source xmlSource = new StreamSource("http://de.wikipedia.org/wiki/Right_Livelihood_Award"); Source xsltSource = new StreamSource(new StringReader(xslt)); TransformerFactory ft = TransformerFactory.newInstance(); Transformer trans = ft.newTransformer(xsltSource); trans.transform(xmlSource, new StreamResult(System.out)); } catch (Exception e) { e.printStackTrace(); } ``` I read the following quesitons here on SO, but they all use another XML-Api: - "DTD download error while parsing XHTML document in XOM" Thanks!

Original source

Related problems