andrewjwelch.com
schema-aware.com
schema-aware XSLT and XQuery examples
SAXONICA

A portable transform across basic and schema-aware processors

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
    
    
<xsl:import-schema schema-location="input.xsd"
        namespace="http://www.example.com"
        use-when="system-property('xsl:is-schema-aware')='yes'" />  
    
    
<xsl:import-schema schema-location="output.xsd"
        use-when="system-property('xsl:is-schema-aware')='yes'" />        

    
<xsl:template match="/" use-when="system-property('xsl:is-schema-aware')='yes'" priority="2">
        
        
<xsl:variable name="input" as="document-node()">
            
<xsl:document validation="strict">
                
<xsl:copy-of select="/" />
            
</xsl:document>
        
</xsl:variable>
        
        
<xsl:result-document validation="strict">
            
<xsl:apply-templates select="$input/the-root-elem" />
        
</xsl:result-document>
        
    
</xsl:template>
    
    
<xsl:template match="/">
        
<xsl:apply-templates select="the-root-elem" />
    
</xsl:template>    
    
    
<xsl:template match="the-root-elem">
        
<xsl:apply-templates />
    
</xsl:template>

</xsl:stylesheet>
The stylesheet contains two root matching templates. The first one has a use-when attribute and a higher priority, which means when the use-when evalutates to true (when the transform is run using a schema-aware processor) that template will be used in preference to the other root matching template. In this case, I validate the input using the $input variable and perform result validation on the output.