<?xml version="1.0" encoding="ISO-8859-1"?>
<!--*****************************************************************************************************************
Written by Giles Hogben,
Joint Research Center, Ispra Italy.
Note this Stylesheet uses 
****************************************************************************************************************-->

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="msxsl xs xsl"
 >
<xsl:key name="DATADEFs" match="DATA-DEF" use="substring-before(@name,'.')"/>
<!--*****************************************************************************************************************
Main processing template
****************************************************************************************************************-->

<xsl:template match="/">
<!--************** Output initial list of root data types inside datatype element ***************************-->
	@br/~<element name="datatype" maxoccurs="1" minoccurs="1">@br/~
<!--********************Group of root data classes ****************************************************************-->
				<choice>
					<xsl:for-each select="//DATA-DEF[generate-id(.)=generate-id(key('DATADEFs', substring-before(@name,'.')))]">
						<element minoccurs="0" maxoccurs="1">
						  		<xsl:attribute name="ref">
			    					<xsl:value-of select="substring-before(@name,'.')"/>
			  					</xsl:attribute>
						@br/~</element>	@br/~
					</xsl:for-each>
				</choice>
	</element>@br/~

<!--*****************************************************************************************************************
For each root data type, output the allowed subtypes and recurse
First Iterate through the key (hash table) of root elements 
****************************************************************************************************************-->
<xsl:for-each select="//DATA-DEF[generate-id(.)=generate-id(key('DATADEFs', substring-before(@name,'.')))]">
				<element  minoccurs="0" maxoccurs="1">
					<xsl:attribute name="name">
	    					<xsl:value-of select="substring-before(@name,'.')"/>
	  				</xsl:attribute>	
<!--********************Sub-elements must be either categories or data types but not both. There may only be one of the subelements allowed-->
				<choice>
<!--******************* Next level of subelements *************************************************************-->		
					<xsl:for-each select="key('DATADEFs', substring-before(@name,'.'))">
						<xsl:call-template name="nextLevel"/>
					</xsl:for-each>				
	</choice>			
		</element>@br/~
<!--****************** Now recursively iterate for all further subtypes    *************************************-->
		<xsl:call-template name="outerlooper">
			<xsl:with-param name="i">0</xsl:with-param>
			<xsl:with-param name="linkTo" select="substring-before(@name,'.')"/>
		</xsl:call-template>
	</xsl:for-each>
</xsl:template>

<!--*****************************************************************************************************************
This template controls the inner iteration Goes deeper and deeper into the tree outputting nodes, always starting from the root 
****************************************************************************************************************-->
<xsl:template name="outerlooper">
	<xsl:param name="i" select="/.."/>
	<xsl:param name="linkTo"  select="/.."/>
	<xsl:choose>
			<xsl:when test="$linkTo!=''">			
<!--***********************If there is a structref, drill into the tree recursively, if not, output the value**-->
					<xsl:variable name="EmptyTest">
							<xsl:call-template name="innerlooper">
								<xsl:with-param name="outerloop" select="$i"/>
								<xsl:with-param name="innerloop" select="0"/>
								<xsl:with-param name="linkTo" select="$linkTo"/>
							</xsl:call-template>
					</xsl:variable>
					<xsl:copy-of select="$EmptyTest"/>
<!--***********************Termination condition and recurse **************************************************-->
					<xsl:if test="string(normalize-space($EmptyTest))!=string('') and $i&lt;5">
						<xsl:call-template name="outerlooper">
							<xsl:with-param name="i">
								<xsl:value-of select="$i+1"/>
							</xsl:with-param>
							<xsl:with-param name="linkTo" select="$linkTo"/>
						</xsl:call-template>
					</xsl:if>
			</xsl:when>
<!--*************************If it is data-def only************************************************************-->
			<xsl:otherwise>
				<xsl:for-each select="//DATA-DEF[generate-id(.)=generate-id(key('DATADEFs', substring-before(@name,'.')))]">
					<xsl:for-each select="key('DATADEFs', substring-before(@name,'.'))">
					@br/~<element  minoccurs="0" maxoccurs="1">
							<xsl:attribute name="name">
 						  		<xsl:value-of select="substring-after(@name,'.')"/>
 							</xsl:attribute>
							<attribute name="short-description" type="xs:string"/>
							<xsl:if test="count(./CATEGORIES/*)!=0">
<!--*************************Categories (as many as you like from the allowed list although repeated elements don't add anything)-->
								<xsl:call-template name="getCategories"/>
<!--*************************End of Categories at this level ***************************************************-->
							</xsl:if>	
					@br/~</element>					
					</xsl:for-each>
				</xsl:for-each>	
			</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!--*****************************************************************************************************************
Template to Recurse down into the tree to iterative depth  
****************************************************************************************************************-->
<xsl:template name="innerlooper">
	<xsl:param name="outerloop" select="/.."/>
	<xsl:param name="innerloop" select="/.."/>
	<xsl:param name="linkTo" select="/.."/>
	<xsl:for-each select="//*[substring-before(@name,'.')=$linkTo]">
		<xsl:choose>
			<xsl:when test="$innerloop=$outerloop">
				<element  minoccurs="0" maxoccurs="1">
					<xsl:attribute name="name">
		  	  			<xsl:value-of select="substring-after(@name,'.')"/>
		  			</xsl:attribute>
					<attribute name="short-description" type="xs:string"/>
					<xsl:variable name="tempStructRef2" select="substring-after(@structref,'#')"/>
						<xsl:if test="count(//DATA-STRUCT[substring-before(@name,'.')=$tempStructRef2])!=0">
							<choice>
								<xsl:for-each select="//DATA-STRUCT[substring-before(@name,'.')=$tempStructRef2]">
									<!--(Uncomment for Iteration number <xsl:value-of  select="$outerloop+3")/> -->
										<xsl:call-template name="nextLevel"/>
									</xsl:for-each>
								</choice>
							</xsl:if>
						</element>
				</xsl:when>
				<xsl:otherwise>
					<xsl:choose>
						<xsl:when test="string(substring-after(@structref,'#'))!=string('')">
							<xsl:call-template name="innerlooper">
								<xsl:with-param name="innerloop" select="$innerloop+1"/>
								<xsl:with-param name="outerloop" select="$outerloop"/>
								<xsl:with-param name="linkTo" select="substring-after(@structref,'#')"/>
							</xsl:call-template>
						</xsl:when>
						<xsl:otherwise>
							<xsl:call-template name="finalLevel"/>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:otherwise>
			</xsl:choose>
	</xsl:for-each>
</xsl:template>


<!--*****************************************************************************************************************
Remove duplicates template
****************************************************************************************************************-->
<xsl:template match="/" mode="pass2"> 
	<xsl:variable name="elements" select=".//*[@name]"/>
		<xsl:for-each select="$elements">
			<xsl:variable name="nameStore" select="@name"/>
			<xsl:if test="generate-id(.)=generate-id(//*[@name=$nameStore])">
				@br/~<xsl:copy-of select="."/>@br/~
			</xsl:if>
		</xsl:for-each>
</xsl:template>

<!--*****************************************************************************************************************
Template to get categories at a particular level
****************************************************************************************************************-->
<xsl:template name="getCategories">
	<element name="CATEGORY" minoccurs="0" maxoccurs="*">
			<attribute name="type">		
				<simpleType>
 						<restriction base="p3p:allCategories">
							<xsl:for-each select="./CATEGORIES/*">			
  									<enumeration>
										<xsl:attribute name="value">
										<xsl:value-of select="local-name()"/>
										</xsl:attribute>
									</enumeration>
  								</xsl:for-each>
  							</restriction>
 						</simpleType>
			</attribute>						
	</element>
</xsl:template>
<!--*****************************************************************************************************************
Template to output an element with a ref attribute
****************************************************************************************************************-->
<xsl:template name="getNextElementRef">
	@br/~<element  minoccurs="0" maxoccurs="1">
			<xsl:attribute name="ref">
				<xsl:value-of select="substring-after(@name,'.')"/>
			</xsl:attribute>
	@br/~</element>
</xsl:template>

<!--*****************************************************************************************************************
Template outputs the next level (used in recursive template)
****************************************************************************************************************-->
<xsl:template name="nextLevel">
	<xsl:choose>
		<xsl:when test="count(./CATEGORIES/*)!=0">
			@br/~<choice>
<!--******************EITHER the next element down ************************************************************-->
					<xsl:call-template name="getNextElementRef"/>
<!--*****************OR Categories (as many as you like from the allowed list although repeated elements don't add anything)-->
					<xsl:call-template name="getCategories"/>
<!--**************** End of Categories at this level ***********************************************************-->
			@br/~</choice>
		</xsl:when>
<!--**************** If there are no categories just output the allowed subtypes at this level *****************-->
		<xsl:otherwise>
			<xsl:call-template name="getNextElementRef"/>
		</xsl:otherwise>	
	</xsl:choose>
</xsl:template>

<!--*****************************************************************************************************************
Template to output final level in a recursion (with a name element rather than a ref element)
****************************************************************************************************************-->
<xsl:template name="finalLevel">
	<xsl:choose>
		<xsl:when test="count(./CATEGORIES/*)!=0">
			<choice>
<!--******************EITHER the next element down ************************************************************-->
				<xsl:call-template name="getFinalElementName"/>
<!--*****************OR Categories (as many as you like from the allowed list although repeated elements don't add anything)-->
				<xsl:call-template name="getCategories"/>
<!--**************** End of Categories at this level ***********************************************************-->
			</choice>
		</xsl:when>
<!--**************** If there are no categories just output the allowed subtypes at this level *****************-->
		<xsl:otherwise>
			<xsl:call-template name="getFinalElementName"/>
		</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!--*****************************************************************************************************************
Template to output a name element alone.
****************************************************************************************************************-->
<xsl:template name="getFinalElementName">
	<element  minoccurs="0" maxoccurs="1">
			<xsl:attribute name="name">
			<xsl:value-of select="substring-after(@name,'.')"/>
		</xsl:attribute>
	</element>
</xsl:template>


</xsl:stylesheet>