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

Using schema-element() to select elements belonging to a substitution group

<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>
        
<xs:schema>            
            
<xs:element name="shapes" type="shapes" />
            
<xs:element name="shape" type="xs:string" />
            
<xs:element name="square" substitutionGroup="shape" />
            
<xs:element name="circle" substitutionGroup="shape" />
            
<xs:element name="triangle" substitutionGroup="shape" />
            
            
<xs:complexType name="shapes">
                
<xs:sequence>
                    
<xs:any maxOccurs="unbounded" />
                
</xs:sequence>
            
</xs:complexType>

        
</xs:schema>
    
</xsl:import-schema>
    
    
<xsl:variable name="input">
        
<shapes xsl:type="shapes">
            
<square>I'm a square</square>
            
<circle>I'm a circle</circle>
            
<triangle>I'm a triangle</triangle>
        
</shapes>
    
</xsl:variable>
    
    
<xsl:template match="/" name="main">     
        
<xsl:value-of select="$input//schema-element(shape)" separator="," />        
    
</xsl:template>   
    
</xsl:stylesheet>
Here the variable $input contains the element shapes which is typed used the xsl:type attribute.
The elements square, circle and triangle are all allowed because they belong to the shape substitution group.
The schema-element() function matches any element that is annotated as an instance of the type defined by the schema element declaration shape, and whose name is either shape or the name of another element in its substitution group - so in this case the square, circle and triangle elements.