Hi,

I have just started using Saxon for some XSLT 2.0 requirements. Before, I ask my question, I want to congratulate the team for an extremely laudable effort for processing XSLT 2.0. The API is very intuitive.

One of the requirements I have is to generate multiple documents (which are text output) out of the transformation. However, I don't want the result text output to be written to the file system, rather, I would like to get some in-memory reference to a stream or a byte array.

1. Can this be done using standard JAXP/TRAX API?

 The XSL looks like below,

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
   
    <!-- Main template -->
    <xsl:template match="/Employee">
        <xsl:result-document method="text">
           <xsl:call-template name="senders-reference"/>
        </xsl:result-document>
        <xsl:result-document method="text">
           <xsl:call-template name="senders-reference"/>
        </xsl:result-document>
    </xsl:template>
   
    <!-- Sender's reference -->
    <xsl:template name="senders-reference">
        <xsl:text>:20:</xsl:text>
        <xsl:value-of select="@Id"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>
   
</xsl:stylesheet>

2. I have implemented this using a custom destination and emitter using the Saxon API as below. Is there a better way of doing this?

public class XslTester {
   
    public static void main(String ... args) throws Exception {
       
        Source xslSource = new StreamSource(XslTester.class.getResourceAsStream("MT103-STD.xsl"));
        Source xmlSource = new StreamSource(XslTester.class.getResourceAsStream("GPG-10.xml"));
       
        Processor processor = new Processor(false);
        XsltCompiler xsltCompiler = processor.newXsltCompiler();
        XsltExecutable xsltExecutable = xsltCompiler.compile(xslSource);
        XsltTransformer xsltTransformer = xsltExecutable.load();
       
        xsltTransformer.setSource(xmlSource);
       
        MyDestination myDestination = new MyDestination();
        xsltTransformer.setDestination(myDestination);
       
        xsltTransformer.transform();
       
        for (String result : myDestination.getResults()) {
            System.err.println(result);
        }
       
    }
   
    private static class MyDestination implements Destination {

        private MyTextEmitter myTextEmitter;
       
        @Override
        public Receiver getReceiver(Configuration configuration) throws SaxonApiException {
            myTextEmitter = new MyTextEmitter(configuration);
            return myTextEmitter;
        }
       
        public List<String> getResults() {
            return myTextEmitter.getResults();
        }
       
    }
   
    private static class MyTextEmitter extends TEXTEmitter {

        private List<String> results = new LinkedList<String>();
        private StringBuilder stringBuilder = null;
        private Configuration configuration;
       
        public MyTextEmitter(Configuration configuration) {
            this.configuration = configuration;
        }
       
        @Override
        protected void openDocument() throws XPathException {
            stringBuilder = new StringBuilder();
        }
       
        @Override
        public void close() throws XPathException {
            results.add(stringBuilder.toString());
        }
       
        @Override
        public Configuration getConfiguration() {
            return configuration;
        }
       
        @Override
        public void characters(CharSequence arg0, int arg1, int arg2) throws XPathException {
            stringBuilder.append(arg0);
        }
        @Override
        public void open() throws XPathException {
            stringBuilder = new StringBuilder();
        }
       
        public List<String> getResults() {
            return results;
        }
       
    }

}

Kind regards
Meeraj