title: Reading xsl transform variables from Java
body: <p>I know that I can pass parameters from Java into an xsl transform, but how can I read variables/parameters back out after the transform is complete?</p>
  
  <p>For example, I have an xml document like this:</p>
  
  <pre><code>&lt;author&gt;
    &lt;name&gt;Barry Bonds&lt;/name&gt;
    &lt;books&gt;
      &lt;book&gt;Hitting Home Runs&lt;/book&gt;
      &lt;book&gt;Cheating at Baseball&lt;/book&gt;
      &lt;book&gt;Nobody Likes Cooperstown Anyway&lt;/book&gt;
    &lt;books&gt;
  &lt;author&gt;
  </code></pre>
  
  <p>In a single transform, I'd like to be able to transform the name element and store that as a variable and also transform the book elements and store them as a second variable.  Then I would like to get access to those 2 variables from Java code, after the transform.</p>
  
  <p>Is this possible, and if so, how is it done?</p>
  
  <p>Thanks to Michael Kay's answer, I now have a solution.  For others who come across this, here's a unit test showing how it works:</p>
  
  <pre><code>import net.sf.saxon.*;
  import org.junit.Test;
  
  import javax.xml.transform.Result;
  import javax.xml.transform.Source;
  import javax.xml.transform.TransformerException;
  import javax.xml.transform.stream.StreamResult;
  import java.io.ByteArrayOutputStream;
  import java.io.UnsupportedEncodingException;
  import java.util.HashMap;
  import java.util.Map;
  
  import static org.junit.Assert.assertEquals;
  
  public class SimpleTransform {
      @Test
      public void splitOutput() throws TransformerException, UnsupportedEncodingException {
          final Map&lt;String, StreamResult&gt; results = new HashMap&lt;String, StreamResult&gt;();
          results.put("test1", new StreamResult(new ByteArrayOutputStream()));
          results.put("test2", new StreamResult(new ByteArrayOutputStream()));
          results.put("test3", new StreamResult(new ByteArrayOutputStream()));
  
          TransformerFactoryImpl factory = new TransformerFactoryImpl();
          Source source = new StandardURIResolver(new Configuration()).resolve("transform.xslt", null);
          Controller xsl = (Controller) factory.newTransformer(source);
          xsl.setOutputURIResolver(new OutputURIResolver() {
              @Override
              public Result resolve(String s, String s1) throws TransformerException {
                  return results.get(s);
              }
  
              @Override
              public void close(Result result) throws TransformerException {
              }
          });
          Source xsd = (Source) Transform.loadDocuments("input.xml", false, null, false);
          StreamResult standardResult = new StreamResult(new ByteArrayOutputStream());
          xsl.transform(xsd, standardResult);
  
          for (Map.Entry&lt;String, StreamResult&gt; stringStreamResultEntry : results.entrySet()) {
              System.out.println(stringStreamResultEntry.getKey() + ": " + ((ByteArrayOutputStream)stringStreamResultEntry.getValue().getOutputStream()).toString("UTF-8"));
          }
  
          assertEquals("&lt;html&gt;\n   &lt;body&gt;test1&lt;/body&gt;\n&lt;/html&gt;", ((ByteArrayOutputStream) results.get("test1").getOutputStream()).toString("UTF-8"));
          assertEquals("&lt;html&gt;\n   &lt;body&gt;test2&lt;/body&gt;\n&lt;/html&gt;", ((ByteArrayOutputStream) results.get("test2").getOutputStream()).toString("UTF-8"));
          assertEquals("&lt;html&gt;\n   &lt;body&gt;test3&lt;/body&gt;\n&lt;/html&gt;", ((ByteArrayOutputStream) results.get("test3").getOutputStream()).toString("UTF-8"));
      }
  }
  </code></pre>