}
Docx4J.toHTML(htmlSettings, outStream, Docx4J.FLAG_EXPORT_PREFER_XSL);
try {
transformer = XmlUtils.getTransformerFactory().newTransformer();
} catch (TransformerConfigurationException e) {
throw new Docx4JException("Exception creating identity transformer to output result: " + e.getMessage(), e);
}
try {
// Resolution of doctype eg
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
// may be extremely slow, so instead of
// transformer.transform(new StreamSource(new ByteArrayInputStream(bytes)), result);
// use
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); // as opposed to XmlUtils.getNewDocumentBuilder()
dbFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
DocumentBuilder db = dbFactory.newDocumentBuilder();
// that feature is enough; alternatively, the below also works. Use both for good measure.
db.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
return new InputSource(new StringReader("")); // Returns a valid dummy source
// returning null here is no good; it seems to cause:
// XMLEntityManager.reset(XMLComponentManager)
// XIncludeAwareParserConfiguration(XML11Configuration).resetCommon()
// with the result that this entity resolver is not used!
}
});
org.w3c.dom.Document doc = null;
if (log.isDebugEnabled()) {
byte[] bytes = outStream.toByteArray();
log.debug(new String(bytes));
doc = db.parse(new ByteArrayInputStream(bytes));
} else {
doc = db.parse(new ByteArrayInputStream(outStream.toByteArray()));
}
transformer.transform(new DOMSource(doc.getDocumentElement()), result);
} catch (TransformerException e) {
throw new Docx4JException("Exception dumping outputstream to output result: " + e.getMessage(), e);
}
}