Hamster
Hamster

Reputation: 680

Adding a catalog to XSLT Saxon s9api in Java

I have the following code which takes XML as input and produces a bunch of other files as output.

   public void transformXml(InputStream inputFileStream, Path outputDir) {

    try {
      Resource resource = resourceLoader
          .getResource("classpath:demo.xslt");

      LOGGER.info("Creating output XMLs and Assessment Report in {}", outputDir);
      final File outputFile = new File(outputDir.toString());

      final Processor processor = getSaxonProcessor();
      XsltCompiler compiler = processor.newXsltCompiler();
      XsltExecutable stylesheet = compiler.compile(new StreamSource(resource.getFile()));
      Xslt30Transformer transformer = stylesheet.load30();

      Serializer out = processor.newSerializer(outputFile);
      out.setOutputProperty(Serializer.Property.METHOD, "xml");
      transformer.transform(new StreamSource(inputFileStream), out);
      LOGGER.debug("Generated DTD XMLs and Assessment Report successfully in {}", outputDir);
    } catch (SaxonApiException e) {
      throw new XmlTransformationException("Error occured during transformation", e);
    } catch (IOException e) {
      throw new XmlTransformationException("Error occured during loading XSLT file", e);
    }
  }

  private Processor getSaxonProcessor() {
    final Configuration configuration = Configuration.newConfiguration();
    configuration.disableLicensing();
    Processor processor = new Processor(configuration);
    return processor;
  }

The XML input contains a DOCTYPE tag which resolves to a DTD that is not available to me. Hence why I am wanting to use a catalog to point it to a dummy DTD which is on my classpath. I am struggling to find a way to this. Most examples that I find out there, are not using the s9api implementation. Any ideas?

Upvotes: 0

Views: 219

Answers (1)

Michael Kay
Michael Kay

Reputation: 163312

Instead of

new StreamSource(inputFileStream)

you should instantiate a SAXSource, containing an XMLReader initialized to use the catalog resolver as its EntityResolver.

If you need to do the same thing for other source documents, such as those read using doc() or document(), you should supply a URIResolver which itself returns a SAXSource initialized in the same way.

There are other ways of doing it using Saxon configuration properties, but I think the above is the simplest.

Upvotes: 1

Related Questions