The only issue with your solution is that you are parsing the stylesheet document more than once, which is a bit wasteful.
 
You can have solved your first problem by making your DocumentBuilderFactory namespace aware, and your second by using setSystemId() on the DOMSource object.
 
Michael Kay
http://www.saxonica.com/


From: Todd Gochenour [mailto:todd.gochenour@gmail.com]
Sent: 11 April 2009 15:50
To: Mailing list for the SAXON XSLT and XQuery processor
Subject: Re: [saxon] Using both Saxon and Xalan

 
I tried using DOMSource as Michael Kay had suggested.  I found that reading a stylesheet file as a DOMSource was problematic because the DocumentBuilderFactory isn't namespace aware by default and passing this DOMSource object to the transform engine was problematic because the base URI isn't defined and so my xsl:includes were throwing an IO exception.  I went with a SAX parser to extract the version attribute instead. 
 
For those who stumble upon this message with a simlar question, here is the solution I came up with:
 
MultiFactoryTest.java

import java.io.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
public class MultiFactoryTest
{
  static String data = "<xml>Hello World</xml>";
  static File template = new File("my-stylesheet.xsl");
  static String version = null;

  public static void main(String[] args)
  {
    TransformerFactory tranFactory = null;
    Transformer aTransformer = null;
    StringWriter result = new StringWriter();
    StreamSource src = new StreamSource( new StringReader( MultiFactoryTest.data ) );
    StreamResult dest = new StreamResult( result );
    try
    {
      XMLReader saxParser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
      saxParser.setContentHandler(new MultiFactoryTest.StylesheetVersionParserHelper());
      saxParser.parse(new InputSource(new FileReader( MultiFactoryTest.template )));
    }
    catch( SAXException e )
    {
      // ignore exception thrown to terminate processing of stylesheet after version is found.
    }
    catch( IOException e )
    {
      // Handle exception
    }
    
    if( "2.0".equals(MultiFactoryTest.version) )
    {
      tranFactory = new net.sf.saxon.TransformerFactoryImpl();
    }
    else
    {
      tranFactory = new org.apache.xalan.processor.TransformerFactoryImpl();
    }
    try
    {
      aTransformer = tranFactory.newTransformer( new StreamSource( MultiFactoryTest.template ) );
      aTransformer.transform( src, dest );
    }
    catch( javax.xml.transform.TransformerException e1 )
    {
      // Handle exception
    }
    finally
    {
      System.out.println( "RESULT:\n"+result.toString() );
    }
  }
 
  private static class StylesheetVersionParserHelper extends DefaultHandler
  {
    public void startElement(String nsURI, String strippedName,
            String tagName, Attributes attributes) throws SAXException
    {
      if( tagName.equalsIgnoreCase("xsl:stylesheet") || tagName.equalsIgnoreCase("xsl:transform") )
      {
        version = attributes.getValue("version");
      }
      throw new SAXException("Terminate after finding xsl stylesheet version="+version);
    }
  }
}

 
 
my-stylesheet.xsl
 
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <html>
            <body>
                <p>HELLO WORLD!</p>
            </body>
        </html>
        <xsl:message>
            XSLT Version: <xsl:copy-of select="system-property('xsl:version')"/>
            XSLT Vendor: <xsl:copy-of select="system-property('xsl:vendor')"/>
            XSLT Vendor URL: <xsl:copy-of select="system-property('xsl:vendor-url')"/>
        </xsl:message>
    </xsl:template>   
</xsl:transform>
 
Output:
 
            XSLT Version: 2.0
            XSLT Vendor: SAXON 9.0.0.2 from Saxonica
            XSLT Vendor URL:
http://www.saxonica.com/
RESULT:
<html>
   <body>
      <p>HELLO WORLD!</p>
   </body>
</html>