I’ve been doing some work which requires me to have local copies of dtd files due to limited connectivity. I’ve been using the Saxon XSLT processor as part of this work and been struggling to get catalog managers working correctly.
Richard Dallaway has an excellent document DTDs and XML Catalogs which provides many helpful clues as to how to proceed with getting the catalog system up and running for parsing and xsl-t.
The following is my addition for anyone trying to get this working with the command line version of Saxon :
java -cp .;./resolver.jar;./saxon7.jar net.sf.saxon.Transform \ -r com.sun.resolver.tools.CatalogResolver\ -x com.sun.resolver.tools.ResolvingXMLReader \ -x com.sun.resolver.tools.ResolvingXMLReader \ mySource.xml myTransform.xsl
I was stuck for a while because I was using only the -r option, this appears to initially work but you need to also specify the -x and -y options to ensure that the SAX parsers used by the transformation engine are also catalog aware.
The next thing to get working was the Transformer within the code itself. I’d had no success by just setting the URIResolver on the TransformerFactory, but given that the above worked it was just a quick dive into the Saxon source to find the required extra params:
transformerFactory.setURIResolver(new CatalogResolver()); transformerFactory.setAttribute("http://saxon.sf.net/feature/sourceParserClass","com.sun.resolver.tools.ResolvingXMLReader"); transformerFactory.setAttribute("http://saxon.sf.net/feature/styleParserClass","com.sun.resolver.tools.ResolvingXMLReader");
This solved my remaining problems and now I can deploy my application without having to ensure the public dtd host is always reachable.