S
Simon Brooke
As various people will have noticed, I've been having a lot of trouble with
XSL lately. Brief history: I wrote myself an XML toolkit back in 2000, and
it worked well enough for me, so it's been little changed since. However,
it works only with an obsolete version of Saxon (6.2.2 I think), and it
has a number of small bugs; and I've at last got to the point where I need
to fix it. And I'm finding it, frankly, absurdly frustrating and
difficult.
But what's frustrating me at this moment is something absurd and weird.
Some weeks ago I did a test with a dummy XSL file called 'dummy.xsl'. Now,
whenever I test with modern Xalan2, I'm persistently getting an error
message:
/home/simon/tmp/test/dummy.xsl; Line #0; Column #0; stylesheet requires
attribute: version
I am really, really not referring to a file called 'dummy.xsl'. I have
grepped through every single file in my working set, and nothing - really
nothing at all - contains the text 'dummy.xsl'. Also, the stylesheet I am
using, really does have a version attribute - see below.
I do not get this message when I'm using my obsolete version of Saxon (and,
indeed, all my transforms work with my obsolete Saxon). So I guessed that
Xalan might use a cache somewhere on my hard disk that I don't know about.
I copied my working files - all three of them, stripping my test down as
far as I could - to my laptop, which should be virgin.
When I run the test, on the laptop, using Xalan2, using GCJ as the Java
implementation I get the 'stylesheet requires attribute: version' error,
but no reference to dummy.xsl. But if I use IBM's Java, I get exactly the
same error message as I get on my development machine - *INCLUDING* the
reference to dummy.xsl!
So I now completely fail to understand where my problem is coming from. I
include my three files below, so that anyone who has the time and patience
can verify my problem and suggest solutions (hopefully not including
either pistols at dawn or a vial of cyanide)
,----[ /home/simon/tmp/xsltest/testharness.sh ]
#!/bin/bash
# XSLPROC=/usr/share/java/xalan2.jar
XSLPROC=/usr/local/lib/java/saxon.jar
export CLASSPATH=".:$XSLPROC"
javac TransformerTestHarness.java
java TransformerTestHarness \
-d org.apache.xerces.dom.DOMImplementationImpl -s test.xsl
`----
,----[ /home/simon/tmp/xsltest/test.xsl ]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<test>
<xsl:apply-templates/>
</test>
</xsl:template>
<xsl:template match="@* node()">
<xsl:copy>
<xsl:apply-templates select="@* node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
`----
,----[ /home/simon/tmp/xsltest/TransformerTestHarness.java ]
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.iutputStream;
import java.io.StringReader;
import java.text.DateFormat;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* Test XSL transformations
*/
public class TransformerTestHarness
{
//~ Static fields/initializers ------------------------------------------
/** A string with parsable content */
public static final String PARSETHIS =
"<parsable><p>Parse me</p></parsable>";
//~ Instance fields -----------------------------------------------------
/** the DOM Implementation I will use */
public DOMImplementation rebus = null;
/** the XSL stylesheet (transform) I will use */
public File stylesheet;
/** DOCUMENT ME! */
public String label = "Transformer test harness";
/**
* A directory into which to write output files - if null, use standard
* out
*/
protected File baseDir = null;
/** A factory class for XSL transformers; */
protected TransformerFactory transformerFactory = null;
//~ Constructors --------------------------------------------------------
/**
* Construct a new test harness
*/
public TransformerTestHarness( )
{
super( );
try
{
transformerFactory = TransformerFactory.newInstance( );
}
catch ( Exception d )
{
System.err.println( "Could not instantiate transformer: " +
d.getMessage( ) );
System.exit( 4 );
}
}
//~ Methods -------------------------------------------------------------
/**
* Generate a document
*
* @return the document
*/
public Document generate( )
{
Document doc = rebus.createDocument( "", "root", null );
Element root = doc.getDocumentElement( );
Element generated = doc.createElement( "generated" );
root.appendChild( generated );
DateFormat df = DateFormat.getDateTimeInstance( );
generated.appendChild( doc.createTextNode( df.format( new
Date( ) ) ) );
try
{
root.appendChild( maybeParse( doc, PARSETHIS ) );
}
catch ( Exception any )
{
System.err.println( "Failed to parse: " + any.getMessage( ) );
}
return doc;
}
/**
* @param args
*/
public static void main( String[] args ) throws Exception
{
TransformerTestHarness tth = new TransformerTestHarness( );
for ( int i = 0; i < args.length; i++ )
{
if ( args.startsWith( "-" ) && ( args.length( ) > 1 ) )
{
switch ( args.charAt( 1 ) )
{
case 'b':
tth.baseDir = new File( args[++i] );
if ( tth.baseDir.exists( ) &&
tth.baseDir.canWrite( ) &&
tth.baseDir.isDirectory( ) )
{
System.err.println( "Using base directory " +
tth.baseDir.getCanonicalPath( ) );
}
else
{
System.err.println( "Bad base directory: " +
args );
}
break;
case 'd':
try
{
tth.rebus =
(DOMImplementation) Class.forName( args[++i] )
.newInstance( );
System.err.println(
"Using DOM implementation of class " +
tth.rebus.getClass( ).getName( ) );
}
catch ( Exception any )
{
System.err.println( "Could not find DOM " +
"implementation " + args );
System.err.println( any.getMessage( ) );
System.exit( 2 );
}
break;
case 's':
tth.stylesheet = new File( args[++i] );
if ( tth.stylesheet.exists( ) &&
tth.stylesheet.canRead( ) )
{
System.err.println( "Using XSL stylesheet " +
tth.stylesheet.getCanonicalPath( ) );
}
else
{
System.err.println( "Can't read stylesheet " +
args );
System.exit( 1 );
}
break;
default:
System.err.println( "Unrecognised arg " + args );
System.exit( 3 );
break;
}
}
else
{
System.err.println( "Unrecognised arg " + args );
System.exit( 3 );
break;
}
}
tth.test( );
}
/**
* Get a suitable output stream - if I have a base directory, a file in
* that directory with this name; else the standard out
*
* @param name a name ofr my file if any
*
* @return an output stream
*
* @throws Exception unlikely
*/
public OutputStream getOutputStream( String name )
throws Exception
{
OutputStream out = System.out;
if ( ( baseDir != null ) && baseDir.exists( ) &&
baseDir.canWrite( ) && baseDir.isDirectory( ) )
{
out = new FileOutputStream( new File( baseDir, name ) );
}
return out;
}
/**
* Run the tests
*/
public void test( )
{
Document generated = generate( );
System.out.println( label );
try
{
System.out.println( "Printer test -> justprint" );
justPrint( generated, "justprint" );
if ( stylesheet != null )
{
DocumentBuilder p =
DocumentBuilderFactory.newInstance( ).newDocumentBuilder( );
Document xslDocument =
p.parse( new InputSource( new FileInputStream( stylesheet ) ) );
System.out.println( "Verify stylesheet -> transform.xsl");
justPrint( xslDocument, "transform.xsl");
System.out.println( "DOM to DOM test -> dom2dom" );
domToDom( generated, xslDocument, "dom2dom" );
System.out.println( "DOM to Stream test -> dom2stream" );
domToDom( generated, xslDocument, "dom2stream" );
}
else
{
System.err.println( "No stylesheet?");
}
}
catch ( Exception e )
{
System.err.println( "Whilst running print test:" );
e.printStackTrace( );
}
}
/**
* Transform from DOM object to DOM object; seralize after
*
* @param doc the document transformed
* @param name the name for printing
*/
protected void domToDom( Document doc, Document xslDocument, String
name )
{
try
{
if ( stylesheet != null )
{
DOMSource domSource = new DOMSource( doc );
DOMResult domResult = new DOMResult( );
transformerFactory.newTransformer( new DOMSource( xslDocument ) )
.transform( domSource, domResult );
Node root = domResult.getNode( );
if ( root instanceof Document )
{
justPrint( (Document) root, name );
}
else
{
System.err.println( "DOM to DOM transform returned " +
root );
}
}
}
catch ( Exception e )
{
System.err.println( "DOM to DOM failed: " + e.getMessage( ) );
e.printStackTrace( );
}
}
/**
* Transform from DOM object to output stream directly
*
* @param doc the document transformed
* @param transform the xsl transform to apply
* @param name the name for printing
*/
protected void domToStream( Document doc, Document transform, String
name )
{
try
{
if ( stylesheet != null )
{
DOMSource domSource = new DOMSource( doc );
StreamResult result =
new StreamResult( getOutputStream( name ) );
transformerFactory.newTransformer( new DOMSource( transform ) )
.transform( domSource, result );
}
}
catch ( Exception e )
{
System.err.println( "DOM to DOM failed: " + e.getMessage( ) );
e.printStackTrace( );
}
}
/**
* Just print the document
*
* @param doc the document to print
* @param name the name of the file to print to
*
* @throws Exception DOCUMENT ME!
*/
protected void justPrint( Document doc, String name )
throws Exception
{
XMLSerializer dickens =
new XMLSerializer( getOutputStream( name ),
new OutputFormat( doc, null, true ) );
dickens.serialize( doc );
}
/**
* Construct a node representing this value. It's perfectly possible (and
* possibly legitimate) that the value of a child should contain embedded
* markup. If so, try to parse a node out of it.
*
* @param doc the document in which the node is to be created
* @param unparsed the string, possibly with embedded markup, to parse
*
* @exception GenerationException if parsing fails
*/
protected Node maybeParse( Document doc, String unparsed )
throws Exception
{
Node val = doc.createTextNode( unparsed ); // safe default
if ( unparsed != null ) // defensive
{
if ( unparsed.indexOf( "<" ) > -1 ) // it looks like markup
{
if ( !unparsed.trim( ).startsWith( "<" ) )
{
// nasty: if it contains markup, but
// isn't contained in markup, the
// parser will barf.
unparsed = "<parsed>" + unparsed + "</parsed>";
}
try
{
DocumentBuilder parser =
DocumentBuilderFactory.newInstance( )
.newDocumentBuilder( );
if ( parser == null )
{
System.err.println( "Could not initialise XML parser" );
}
InputSource i =
new InputSource( new StringReader( unparsed ) );
Document parsed = parser.parse( i );
if ( parsed != null )
{
Node root = parsed.getDocumentElement( );
val = doc.importNode( root, true );
}
}
catch ( Exception e )
{
System.err.println( "Could not parse '" + unparsed +
"'as XML" );
e.printStackTrace( System.err );
}
}
}
return val;
}
}
`----
,----[ Sample output with Saxon (i.e. what I think you should get) ]
Using DOM implementation of class
org.apache.xerces.dom.DOMImplementationImpl
Using XSL stylesheet /home/simon/tmp/xsltest/test.xsl
Transformer test harness
Printer test -> justprint
<?xml version="1.0"?>
<root>
<generated>18-Mar-2007 14:33:26</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
Verify stylesheet -> transform.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<test>
<xsl:apply-templates/>
</test>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
DOM to DOM test -> dom2dom
<?xml version="1.0"?>
<test>
<root>
<generated>18-Mar-2007 14:33:26</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
</test>
DOM to Stream test -> dom2stream
<?xml version="1.0"?>
<test>
<root>
<generated>18-Mar-2007 14:33:26</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
</test>
,----[ Sample output with Xalan2 ]
Using DOM implementation of class
org.apache.xerces.dom.DOMImplementationImpl
Using XSL stylesheet /home/simon/tmp/xsltest/test.xsl
Transformer test harness
Printer test -> justprint
<?xml version="1.0"?>
<root>
<generated>18-Mar-2007 14:34:50</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
Verify stylesheet -> transform.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<test>
<xsl:apply-templates/>
</test>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
DOM to DOM test -> dom2dom
/home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0; stylesheet requires
attribute: version
file:///home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0;
java.util.EmptyStackException
DOM to Stream test -> dom2stream
/home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0; stylesheet requires
attribute: version
file:///home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0;
java.util.EmptyStackException
XSL lately. Brief history: I wrote myself an XML toolkit back in 2000, and
it worked well enough for me, so it's been little changed since. However,
it works only with an obsolete version of Saxon (6.2.2 I think), and it
has a number of small bugs; and I've at last got to the point where I need
to fix it. And I'm finding it, frankly, absurdly frustrating and
difficult.
But what's frustrating me at this moment is something absurd and weird.
Some weeks ago I did a test with a dummy XSL file called 'dummy.xsl'. Now,
whenever I test with modern Xalan2, I'm persistently getting an error
message:
/home/simon/tmp/test/dummy.xsl; Line #0; Column #0; stylesheet requires
attribute: version
I am really, really not referring to a file called 'dummy.xsl'. I have
grepped through every single file in my working set, and nothing - really
nothing at all - contains the text 'dummy.xsl'. Also, the stylesheet I am
using, really does have a version attribute - see below.
I do not get this message when I'm using my obsolete version of Saxon (and,
indeed, all my transforms work with my obsolete Saxon). So I guessed that
Xalan might use a cache somewhere on my hard disk that I don't know about.
I copied my working files - all three of them, stripping my test down as
far as I could - to my laptop, which should be virgin.
When I run the test, on the laptop, using Xalan2, using GCJ as the Java
implementation I get the 'stylesheet requires attribute: version' error,
but no reference to dummy.xsl. But if I use IBM's Java, I get exactly the
same error message as I get on my development machine - *INCLUDING* the
reference to dummy.xsl!
So I now completely fail to understand where my problem is coming from. I
include my three files below, so that anyone who has the time and patience
can verify my problem and suggest solutions (hopefully not including
either pistols at dawn or a vial of cyanide)
,----[ /home/simon/tmp/xsltest/testharness.sh ]
#!/bin/bash
# XSLPROC=/usr/share/java/xalan2.jar
XSLPROC=/usr/local/lib/java/saxon.jar
export CLASSPATH=".:$XSLPROC"
javac TransformerTestHarness.java
java TransformerTestHarness \
-d org.apache.xerces.dom.DOMImplementationImpl -s test.xsl
`----
,----[ /home/simon/tmp/xsltest/test.xsl ]
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<test>
<xsl:apply-templates/>
</test>
</xsl:template>
<xsl:template match="@* node()">
<xsl:copy>
<xsl:apply-templates select="@* node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
`----
,----[ /home/simon/tmp/xsltest/TransformerTestHarness.java ]
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.iutputStream;
import java.io.StringReader;
import java.text.DateFormat;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* Test XSL transformations
*/
public class TransformerTestHarness
{
//~ Static fields/initializers ------------------------------------------
/** A string with parsable content */
public static final String PARSETHIS =
"<parsable><p>Parse me</p></parsable>";
//~ Instance fields -----------------------------------------------------
/** the DOM Implementation I will use */
public DOMImplementation rebus = null;
/** the XSL stylesheet (transform) I will use */
public File stylesheet;
/** DOCUMENT ME! */
public String label = "Transformer test harness";
/**
* A directory into which to write output files - if null, use standard
* out
*/
protected File baseDir = null;
/** A factory class for XSL transformers; */
protected TransformerFactory transformerFactory = null;
//~ Constructors --------------------------------------------------------
/**
* Construct a new test harness
*/
public TransformerTestHarness( )
{
super( );
try
{
transformerFactory = TransformerFactory.newInstance( );
}
catch ( Exception d )
{
System.err.println( "Could not instantiate transformer: " +
d.getMessage( ) );
System.exit( 4 );
}
}
//~ Methods -------------------------------------------------------------
/**
* Generate a document
*
* @return the document
*/
public Document generate( )
{
Document doc = rebus.createDocument( "", "root", null );
Element root = doc.getDocumentElement( );
Element generated = doc.createElement( "generated" );
root.appendChild( generated );
DateFormat df = DateFormat.getDateTimeInstance( );
generated.appendChild( doc.createTextNode( df.format( new
Date( ) ) ) );
try
{
root.appendChild( maybeParse( doc, PARSETHIS ) );
}
catch ( Exception any )
{
System.err.println( "Failed to parse: " + any.getMessage( ) );
}
return doc;
}
/**
* @param args
*/
public static void main( String[] args ) throws Exception
{
TransformerTestHarness tth = new TransformerTestHarness( );
for ( int i = 0; i < args.length; i++ )
{
if ( args.startsWith( "-" ) && ( args.length( ) > 1 ) )
{
switch ( args.charAt( 1 ) )
{
case 'b':
tth.baseDir = new File( args[++i] );
if ( tth.baseDir.exists( ) &&
tth.baseDir.canWrite( ) &&
tth.baseDir.isDirectory( ) )
{
System.err.println( "Using base directory " +
tth.baseDir.getCanonicalPath( ) );
}
else
{
System.err.println( "Bad base directory: " +
args );
}
break;
case 'd':
try
{
tth.rebus =
(DOMImplementation) Class.forName( args[++i] )
.newInstance( );
System.err.println(
"Using DOM implementation of class " +
tth.rebus.getClass( ).getName( ) );
}
catch ( Exception any )
{
System.err.println( "Could not find DOM " +
"implementation " + args );
System.err.println( any.getMessage( ) );
System.exit( 2 );
}
break;
case 's':
tth.stylesheet = new File( args[++i] );
if ( tth.stylesheet.exists( ) &&
tth.stylesheet.canRead( ) )
{
System.err.println( "Using XSL stylesheet " +
tth.stylesheet.getCanonicalPath( ) );
}
else
{
System.err.println( "Can't read stylesheet " +
args );
System.exit( 1 );
}
break;
default:
System.err.println( "Unrecognised arg " + args );
System.exit( 3 );
break;
}
}
else
{
System.err.println( "Unrecognised arg " + args );
System.exit( 3 );
break;
}
}
tth.test( );
}
/**
* Get a suitable output stream - if I have a base directory, a file in
* that directory with this name; else the standard out
*
* @param name a name ofr my file if any
*
* @return an output stream
*
* @throws Exception unlikely
*/
public OutputStream getOutputStream( String name )
throws Exception
{
OutputStream out = System.out;
if ( ( baseDir != null ) && baseDir.exists( ) &&
baseDir.canWrite( ) && baseDir.isDirectory( ) )
{
out = new FileOutputStream( new File( baseDir, name ) );
}
return out;
}
/**
* Run the tests
*/
public void test( )
{
Document generated = generate( );
System.out.println( label );
try
{
System.out.println( "Printer test -> justprint" );
justPrint( generated, "justprint" );
if ( stylesheet != null )
{
DocumentBuilder p =
DocumentBuilderFactory.newInstance( ).newDocumentBuilder( );
Document xslDocument =
p.parse( new InputSource( new FileInputStream( stylesheet ) ) );
System.out.println( "Verify stylesheet -> transform.xsl");
justPrint( xslDocument, "transform.xsl");
System.out.println( "DOM to DOM test -> dom2dom" );
domToDom( generated, xslDocument, "dom2dom" );
System.out.println( "DOM to Stream test -> dom2stream" );
domToDom( generated, xslDocument, "dom2stream" );
}
else
{
System.err.println( "No stylesheet?");
}
}
catch ( Exception e )
{
System.err.println( "Whilst running print test:" );
e.printStackTrace( );
}
}
/**
* Transform from DOM object to DOM object; seralize after
*
* @param doc the document transformed
* @param name the name for printing
*/
protected void domToDom( Document doc, Document xslDocument, String
name )
{
try
{
if ( stylesheet != null )
{
DOMSource domSource = new DOMSource( doc );
DOMResult domResult = new DOMResult( );
transformerFactory.newTransformer( new DOMSource( xslDocument ) )
.transform( domSource, domResult );
Node root = domResult.getNode( );
if ( root instanceof Document )
{
justPrint( (Document) root, name );
}
else
{
System.err.println( "DOM to DOM transform returned " +
root );
}
}
}
catch ( Exception e )
{
System.err.println( "DOM to DOM failed: " + e.getMessage( ) );
e.printStackTrace( );
}
}
/**
* Transform from DOM object to output stream directly
*
* @param doc the document transformed
* @param transform the xsl transform to apply
* @param name the name for printing
*/
protected void domToStream( Document doc, Document transform, String
name )
{
try
{
if ( stylesheet != null )
{
DOMSource domSource = new DOMSource( doc );
StreamResult result =
new StreamResult( getOutputStream( name ) );
transformerFactory.newTransformer( new DOMSource( transform ) )
.transform( domSource, result );
}
}
catch ( Exception e )
{
System.err.println( "DOM to DOM failed: " + e.getMessage( ) );
e.printStackTrace( );
}
}
/**
* Just print the document
*
* @param doc the document to print
* @param name the name of the file to print to
*
* @throws Exception DOCUMENT ME!
*/
protected void justPrint( Document doc, String name )
throws Exception
{
XMLSerializer dickens =
new XMLSerializer( getOutputStream( name ),
new OutputFormat( doc, null, true ) );
dickens.serialize( doc );
}
/**
* Construct a node representing this value. It's perfectly possible (and
* possibly legitimate) that the value of a child should contain embedded
* markup. If so, try to parse a node out of it.
*
* @param doc the document in which the node is to be created
* @param unparsed the string, possibly with embedded markup, to parse
*
* @exception GenerationException if parsing fails
*/
protected Node maybeParse( Document doc, String unparsed )
throws Exception
{
Node val = doc.createTextNode( unparsed ); // safe default
if ( unparsed != null ) // defensive
{
if ( unparsed.indexOf( "<" ) > -1 ) // it looks like markup
{
if ( !unparsed.trim( ).startsWith( "<" ) )
{
// nasty: if it contains markup, but
// isn't contained in markup, the
// parser will barf.
unparsed = "<parsed>" + unparsed + "</parsed>";
}
try
{
DocumentBuilder parser =
DocumentBuilderFactory.newInstance( )
.newDocumentBuilder( );
if ( parser == null )
{
System.err.println( "Could not initialise XML parser" );
}
InputSource i =
new InputSource( new StringReader( unparsed ) );
Document parsed = parser.parse( i );
if ( parsed != null )
{
Node root = parsed.getDocumentElement( );
val = doc.importNode( root, true );
}
}
catch ( Exception e )
{
System.err.println( "Could not parse '" + unparsed +
"'as XML" );
e.printStackTrace( System.err );
}
}
}
return val;
}
}
`----
,----[ Sample output with Saxon (i.e. what I think you should get) ]
Using DOM implementation of class
org.apache.xerces.dom.DOMImplementationImpl
Using XSL stylesheet /home/simon/tmp/xsltest/test.xsl
Transformer test harness
Printer test -> justprint
<?xml version="1.0"?>
<root>
<generated>18-Mar-2007 14:33:26</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
Verify stylesheet -> transform.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<test>
<xsl:apply-templates/>
</test>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
DOM to DOM test -> dom2dom
<?xml version="1.0"?>
<test>
<root>
<generated>18-Mar-2007 14:33:26</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
</test>
DOM to Stream test -> dom2stream
<?xml version="1.0"?>
<test>
<root>
<generated>18-Mar-2007 14:33:26</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
</test>
,----[ Sample output with Xalan2 ]
Using DOM implementation of class
org.apache.xerces.dom.DOMImplementationImpl
Using XSL stylesheet /home/simon/tmp/xsltest/test.xsl
Transformer test harness
Printer test -> justprint
<?xml version="1.0"?>
<root>
<generated>18-Mar-2007 14:34:50</generated>
<parsable>
<p>Parse me</p>
</parsable>
</root>
Verify stylesheet -> transform.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<test>
<xsl:apply-templates/>
</test>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
DOM to DOM test -> dom2dom
/home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0; stylesheet requires
attribute: version
file:///home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0;
java.util.EmptyStackException
DOM to Stream test -> dom2stream
/home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0; stylesheet requires
attribute: version
file:///home/simon/tmp/xsltest/dummy.xsl; Line #0; Column #0;
java.util.EmptyStackException