The aim was to create a vaildator that takes an XML document of the following form and annotate
it to state whether each individual siteswap was valid or invalid:

<?xml version="1.0" encoding="ISO-8859-1"?>
<siteswaps>
  <siteswap>34535</siteswap>
	<siteswap>543</siteswap>
	<siteswap>441</siteswap>
	<siteswap>97531</siteswap>
	<siteswap>24234</siteswap>
</siteswaps>

generating the following:

<?xml version="1.0" encoding="UTF-8"?>
<siteswaps>
	<siteswap valid="true">34535</siteswap>
	<siteswap valid="false">543</siteswap>
	<siteswap valid="true">441</siteswap>
	<siteswap valid="true">97531</siteswap>
	<siteswap valid="true">24234</siteswap>
</siteswaps>


However, the strength of XSLT lies in its ability to perform operations based on the structure
of the document tree, rather than text processing. Therefore the above document is not in a very
XSLT friendly format making it very difficult to validate it using a single tranformation.

After a bit of head scratching I decided to tackle this problem by creating a chain of transformations,
each on performing a specific task. This is much closer to the spirit of what XSLT was intended for.


======= Transformation #1: "expand_throws.xsl"  =======

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes"/>
	
	<xsl:template match="@*|node()">
	  <xsl:copy>
	    <xsl:apply-templates select="@*|node()"/>
	  </xsl:copy>
	</xsl:template>
	  
	<xsl:template match="siteswap">
		<xsl:element name="siteswap">
			<xsl:attribute name="value">
    			<xsl:value-of select="."/>
    		</xsl:attribute>
	    	<xsl:call-template name="splitThrows">
		    	<xsl:with-param name="siteswap" select="."/>
		    </xsl:call-template>
	  	</xsl:element>
	</xsl:template>
	
	<xsl:template name="splitThrows">
		<xsl:param name="siteswap"/>
		<xsl:if test="string-length($siteswap)>0">
			<xsl:element name="beat">
				<xsl:element name="throw">
					<xsl:value-of select="substring($siteswap,1,1)"/>
				</xsl:element>
			</xsl:element>
			<xsl:call-template name="splitThrows">
		    	<xsl:with-param name="siteswap" select="substring($siteswap,2,string-length($siteswap)-1)"/>
		    </xsl:call-template>
		</xsl:if>		
	</xsl:template>
</xsl:stylesheet>


The above transformation splits each siteswap up into a collection of beats, each on containing a throw.
for example the following XML file:

<?xml version="1.0" encoding="ISO-8859-1"?>
<siteswaps>
	<siteswap>4411</siteswap>
</siteswaps>

will be transformed to become the following:

<?xml version="1.0" encoding="UTF-8"?>
<siteswaps>
	<siteswap value="4411">
		<beat>
			<throw>4</throw>
		</beat>
		<beat>
			<throw>4</throw>
		</beat>
		<beat>
			<throw>1</throw>
		</beat>
		<beat>
			<throw>1</throw>
		</beat>
	</siteswap>
</siteswaps>



======= Transformation #2: "locate_catches.xsl"  =======

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes"/>
	
	<xsl:template match="@*|node()">
	  <xsl:copy>
	    <xsl:apply-templates select="@*|node()"/>
	  </xsl:copy>
	</xsl:template>
	  
	<xsl:template match="siteswap">
		<xsl:element name="siteswap">
			<xsl:apply-templates select="@*"/>
			<xsl:variable name="siteswapLength" select="count(beat)"/>
			
			<xsl:for-each select="beat">
				<xsl:element name="beat">
					<xsl:variable name="thisBeatPos" select="position()"/>
					
					<xsl:apply-templates select="throw"/>
					
					<xsl:for-each select="../beat/throw">
						<xsl:if test="((number(.)+position()) mod $siteswapLength)+1 = $thisBeatPos">
							<xsl:element name="catch"/>
						</xsl:if>
					</xsl:for-each>
				</xsl:element>
			</xsl:for-each>		
		</xsl:element>
	</xsl:template>
	
</xsl:stylesheet>


The above transformation considers each beat in turn and inserts a catch element if
any of the throws within the siteswap are caught there. for example, the following XML:


<?xml version="1.0" encoding="UTF-8"?>
<siteswaps>
	<siteswap value="4411">
		<beat>
			<throw>4</throw>
		</beat>
		<beat>
			<throw>4</throw>
		</beat>
		<beat>
			<throw>1</throw>
		</beat>
		<beat>
			<throw>1</throw>
		</beat>
	</siteswap>
</siteswaps>

Is transformed to:

<?xml version="1.0" encoding="UTF-8"?>
<siteswaps>
	<siteswap value="4411">
		<beat>
			<throw>4</throw>
			<catch/>
		</beat>
		<beat>
			<throw>4</throw>
			<catch/>
			<catch/>
		</beat>
		<beat>
			<throw>1</throw>
			<catch/>
		</beat>
		<beat>
			<throw>1</throw>
		</beat>
	</siteswap>
</siteswaps>

You should already be able to see that this siteswap is not valid, due to their being two
catches made on the second beat, but just a single throw.


======= Transformation #3: "validate_siteswap.xsl"  =======

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output indent="yes"/>
	
	<xsl:template match="@*|node()">
	  <xsl:copy>
	    <xsl:apply-templates select="@*|node()"/>
	  </xsl:copy>
	</xsl:template>
	  
	<xsl:template match="siteswap">
		<xsl:element name="siteswap">		
			<xsl:attribute name="valid">				
    			<xsl:variable name="invalid">
    				<xsl:call-template name="findMultipleCatches"/>
    			</xsl:variable>
    			<xsl:choose>
    				<xsl:when test="$invalid=''">
    					<xsl:text>true</xsl:text>
    				</xsl:when>
    				<xsl:otherwise>
    					<xsl:text>false</xsl:text>
    				</xsl:otherwise>
    			</xsl:choose>
    		</xsl:attribute>    		
    		<xsl:value-of select="@value"/>    		        		
	  	</xsl:element>
	</xsl:template>
	
	<xsl:template name="findMultipleCatches">
		<xsl:for-each select="beat">
			<xsl:if test="count(catch) &gt; 1">
				<xsl:text>x</xsl:text>
			</xsl:if>
		</xsl:for-each>
	</xsl:template>
		
</xsl:stylesheet>


The final transformation inspects all the beats within each siteswap to find multiple 
catches. The document is transformed back into its original form, with the addition
of a valid attribute. for example, the following XML:

<?xml version="1.0" encoding="UTF-8"?>
<siteswaps>
	<siteswap value="4411">
		<beat>
			<throw>4</throw>
			<catch/>
		</beat>
		<beat>
			<throw>4</throw>
			<catch/>
			<catch/>
		</beat>
		<beat>
			<throw>1</throw>
			<catch/>
		</beat>
		<beat>
			<throw>1</throw>
		</beat>
	</siteswap>
</siteswaps>

Is transformed to:

<?xml version="1.0" encoding="UTF-8"?>
<siteswaps>
	<siteswap valid="false">4411</siteswap>
</siteswaps>


======= Putting it all together  =======

if you use Ant, the following build file will execute the transformations
in the desired order:

<?xml version="1.0"?>
<project name="validate cocoon" default="validate" basedir=".">

    <target name="validate">
        <xslt in="siteswaps.xml"
           	out="siteswaps_throws_expanded.xml"
           	style="expand_throws.xsl" />
        <xslt in="siteswaps_throws_expanded.xml"
           	out="siteswaps_catches.xml"
           	style="locate_catches.xsl" />
        <xslt in="siteswaps_catches.xml"
           	out="siteswaps_validated.xml"
           	style="validate_siteswap.xsl" />
    </target>   
	
</project>

