<?xml version="1.0"?>
<xsl:stylesheet xmlns="http://www.ivoa.net/xml/ADQL/v0.7.4" xmlns:ad="http://www.ivoa.net/xml/ADQL/v0.7.4"
xmlns:ns1="http://www.ivoa.net/xml/ADQL/v0.7.4"
 xmlns:q1="urn:nvo-region" xmlns:q2="urn:nvo-coords" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
	<!-- 
	- Stylesheet to convert ADQL version 0.7.4 to an SQL String 
	- Version 1.0 - Initial Revision
	- Ramon Williamson, National Center for SuperComputing Applications
	- April 1, 2004
	- Based on the schema: http://www.ivoa.net/internal/IVOA/IvoaVOQL/ADQL-0.7.4.xsd
	-->
	<xsl:output method="text"/>
	<xsl:template match="/">
		<xsl:apply-templates select="/*"/>
	</xsl:template>
	<xsl:template match="/*">
		<xsl:text>SELECT </xsl:text>
		<xsl:apply-templates select="Allow"/>
		<xsl:apply-templates select="Restrict"/>
		<xsl:apply-templates select="SelectionList"/>
		<xsl:text> FROM </xsl:text>
		<xsl:apply-templates select="From"/>
		<xsl:apply-templates select="Where"/>
		<xsl:apply-templates select="GroupBy"/>
		<xsl:apply-templates select="Having"/>
		<xsl:apply-templates select="OrderBy"/>
	</xsl:template>
	<!-- 
     -  Allow Template 
     -->
	<xsl:template match="Allow">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="@Option"/>
			<xsl:text> </xsl:text>
		</xsl:if>
	</xsl:template>
	<!-- 
     -  Restrict Template 
     -->
	<xsl:template match="Restrict">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text>TOP </xsl:text>
			<xsl:value-of select="@Top"/>
			<xsl:text> </xsl:text>
		</xsl:if>
	</xsl:template>
	<!-- 
     -  OrderBy Template 
     -->
	<xsl:template match="OrderBy">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text> ORDER BY </xsl:text>
			<xsl:variable name="string">
				<xsl:for-each select="Item">
					<xsl:apply-templates select="*[1]"/>
					<xsl:choose>
						<xsl:when test="*[2] = Order">
							<xsl:text> </xsl:text>
							<xsl:value-of select="*[2]/@Direction"/>
							<xsl:text>, </xsl:text>
						</xsl:when>
						<xsl:otherwise>
							<xsl:text>, </xsl:text>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 2)"/>
		</xsl:if>
	</xsl:template>
	<!-- 
     -  SelectionList Template 
     -->
	<xsl:template match="SelectionList">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:variable name="string">
				<xsl:for-each select="Item">
					<xsl:choose>
						<xsl:when test="@xsi:type='ns1:allSelectionItemType'">
							<xsl:text> * </xsl:text>
							<xsl:text>, </xsl:text>
						</xsl:when>
						<xsl:when test="@xsi:type='allSelectionItemType'">
							<xsl:text> * </xsl:text>
							<xsl:text>, </xsl:text>
						</xsl:when>
						<xsl:when test="@xsi:type='ns1:aliasSelectionItemType'">
							<xsl:apply-templates select="*"/>
							<xsl:text> AS </xsl:text>
							<xsl:value-of select="@As"/>
							<xsl:text>, </xsl:text>
						</xsl:when>
						<xsl:when test="@xsi:type='aliasSelectionItemType'">
							<xsl:apply-templates select="*"/>
							<xsl:text> AS </xsl:text>
							<xsl:value-of select="@As"/>
							<xsl:text>, </xsl:text>
						</xsl:when>
						<xsl:otherwise>
							<xsl:apply-templates select="."/>
							<xsl:text>, </xsl:text>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 2)"/>
		</xsl:if>
	</xsl:template>
	<!-- 
     -  From Template 
     -->
	<xsl:template match="From">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:variable name="string">
				<xsl:for-each select="Table">
					<xsl:value-of select="@Name"/>
					<xsl:text> </xsl:text>
					<xsl:value-of select="@Alias"/>
					<xsl:text>, </xsl:text>
				</xsl:for-each>
				<xsl:for-each select="ArchiveTable">
					<xsl:value-of select="@Name"/>
					<xsl:text> </xsl:text>
					<xsl:value-of select="@Alias"/>
					<xsl:text>, </xsl:text>
				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 2)"/>
		</xsl:if>
	</xsl:template>
	<!-- Search Types -->
	<!--
     -  Intersection Search:  a AND b
     -->
	<xsl:template match="*[@xsi:type='ns1:intersectionSearchType'] | 
           *[@xsi:type='intersectionSearchType'] ">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="*[1]"/>
			<xsl:text> AND </xsl:text>
			<xsl:apply-templates select="*[2]"/>
		</xsl:if>
	</xsl:template>
	<!-- 
     -  Union: a OR b
     -->
	<xsl:template match="*[@xsi:type='ns1:unionSearchType'] | 
            *[@xsi:type='unionSearchType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="*[1]"/>
			<xsl:text> OR </xsl:text>
			<xsl:apply-templates select="*[2]"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Circle (a)
     -->
	<xsl:template match="*[@xsi:type='ns1:regionSearchType'] | 
           *[@xsi:type='regionSearchType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text>REGION('Circle </xsl:text>
			<xsl:choose>
				<xsl:when test="Region/q1:Center/Pos2Vector">
					<xsl:text>J2000 </xsl:text>
					<xsl:apply-templates select="Region/q1:Center/Pos2Vector/CoordValue"/>
					<xsl:text> </xsl:text>
					<xsl:value-of select="Region/q1:Radius"/>
				</xsl:when>
				<xsl:when test="Region/q1:Center/Pos3Vector">
					<xsl:text>Cartesian </xsl:text>
					<xsl:apply-templates select="Region/q1:Center/Pos3Vector/CoordValue"/>
					<xsl:text> </xsl:text>
					<xsl:value-of select="Region/q1:Radius"/>
				</xsl:when>
			</xsl:choose>
			<xsl:text>') </xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
     -  XMatch
     -->
	<xsl:template match="*[@xsi:type='ns1:xMatchType'] | *[@xsi:type='xMatchType']  ">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text>XMATCH(</xsl:text>
			<xsl:variable name="string">
				<xsl:for-each select="Table">
					<xsl:if test="@xsi:type='ns1:includeTableType'">
						<xsl:value-of select="@Name"/>
						<xsl:text>, </xsl:text>
					</xsl:if>
					<xsl:if test="@xsi:type='includeTableType'">
						<xsl:value-of select="@Name"/>
						<xsl:text>, </xsl:text>
					</xsl:if>
					<xsl:if test="@xsi:type='ns1:dropTableType'">
						<xsl:text>!</xsl:text>
						<xsl:value-of select="@Name"/>
						<xsl:text>, </xsl:text>
					</xsl:if>
					<xsl:if test="@xsi:type='dropTableType'">
						<xsl:text>!</xsl:text>
						<xsl:value-of select="@Name"/>
						<xsl:text>, </xsl:text>
					</xsl:if>

				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 2)"/>
			<xsl:text>)</xsl:text>
			<xsl:text> </xsl:text>
			<xsl:value-of select="Nature"/>
			<xsl:text> </xsl:text>
			<xsl:value-of select="Sigma/@Value"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Simple binary operator comparison:  a op b
     -->
	<xsl:template match="*[@xsi:type='ns1:comparisonPredType'] | *[@xsi:type='comparisonPredType'] ">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:variable name="comp">
				<xsl:value-of select="@Comparison"/>
			</xsl:variable>
			<xsl:apply-templates select="Arg[1]"/>
			<xsl:text> </xsl:text>
			<xsl:value-of select="$comp"/>
			<xsl:text> </xsl:text>
			<xsl:apply-templates select="Arg[2]"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Negates comparisons below:  a NOT comp b
     -->
	<xsl:template match="*[@xsi:type='ns1:inverseSearchType'] | *[@xsi:type='inverseSearchType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text>NOT </xsl:text>
			<xsl:apply-templates select="*"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Like comparison:  a LIKE b
     -->
	<xsl:template match="*[@xsi:type='ns1:likePredType'] | *[@xsi:type='likePredType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="Arg"/>
			<xsl:text> LIKE </xsl:text>
			<xsl:apply-templates select="Pattern/Literal"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  NotLike comparison:  a NOT LIKE b
     -->
	<xsl:template match="*[@xsi:type='ns1:notLikePredType'] | *[@xsi:type='notLikePredType'] ">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="Arg"/>
			<xsl:text> NOT LIKE </xsl:text>
			<xsl:apply-templates select="Pattern/Literal"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Between comparison:  
     	a BETWEEN b AND c, 
     -->
	<xsl:template match="*[@xsi:type='ns1:betweenPredType'] | *[@xsi:type='betweenPredType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="*[1]"/>
			<xsl:text> BETWEEN </xsl:text>
			<xsl:apply-templates select="*[2]"/>
			<xsl:text> AND </xsl:text>
			<xsl:apply-templates select="*[3]"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  NotBetween comparison:  
     	  a NOT BETWEEN b AND c, 
     -->
	<xsl:template match="*[@xsi:type='ns1:notBetweenPredType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="*[1]"/>
			<xsl:text> NOT BETWEEN </xsl:text>
			<xsl:apply-templates select="*[2]"/>
			<xsl:text> AND </xsl:text>
			<xsl:apply-templates select="*[3]"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Closed (a)
     -->
	<xsl:template match="*[@xsi:type='ns1:closedSearchType'] | *[@xsi:type='closedSearchType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text>(</xsl:text>
			<xsl:apply-templates select="*"/>
			<xsl:text>)</xsl:text>
		</xsl:if>
	</xsl:template>
	<!-- Where Template -->
	<xsl:template match="Where">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text> WHERE </xsl:text>
			<xsl:apply-templates select="Condition"/>
		</xsl:if>
	</xsl:template>
	<!-- GroupBy Template -->
	<xsl:template match="GroupBy">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text> GROUP BY </xsl:text>
			<xsl:variable name="string">
				<xsl:for-each select="*">
					<xsl:apply-templates select="."/>
					<xsl:text>, </xsl:text>
				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 2)"/>
		</xsl:if>
	</xsl:template>
	<!-- Having Template -->
	<xsl:template match="Having">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text> HAVING </xsl:text>
			<xsl:apply-templates select="*"/>
		</xsl:if>
	</xsl:template>
	<xsl:template match="Column">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="@Table"/>
			<xsl:text>.</xsl:text>
			<xsl:value-of select="@Name"/>
		</xsl:if>
	</xsl:template>
	<xsl:template match="Having">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text> HAVING </xsl:text>
			<xsl:apply-templates select="*"/>
		</xsl:if>
	</xsl:template>
	<!-- scalarExpressionTypes -->
	<!--
     -  Table Columns (columnReferenceType)
     -->
	<xsl:template match="*[@xsi:type='ns1:columnReferenceType'] |
        *[@xsi:type='columnReferenceType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="@Table"/>
			<xsl:text>.</xsl:text>
			<xsl:value-of select="@Name"/>
		</xsl:if>
	</xsl:template>
	<!-- 
     -  Unary Operation
     -->
	<xsl:template match="*[@xsi:type='ns1:unaryExprType'] | 
        *[@xsi:type='unaryExprType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="Arg"/>
			<xsl:text> </xsl:text>
			<xsl:value-of select="@Oper"/>
			<xsl:text> </xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
     -  Binary Operation
     -->
	<xsl:template match="*[@xsi:type='ns1:binaryExprType'] | 
       *[@xsi:type='binaryExprType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="Arg[1]"/>
			<xsl:text> </xsl:text>
			<xsl:value-of select="@Oper"/>
			<xsl:text> </xsl:text>
			<xsl:apply-templates select="Arg[2]"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Atom Expression
     -->
	<xsl:template match="*[@xsi:type='ns1:atomType'] | 
       *[@xsi:type='atomType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:apply-templates select="*"/>
		</xsl:if>
	</xsl:template>
	<!--
     -  Closed (a)
     -->
	<xsl:template match="*[@xsi:type='ns1:closedExprType'] | 
           *[@xsi:type='closedExprType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:text>(</xsl:text>
			<xsl:apply-templates select="*"/>
			<xsl:text>)</xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
     -  Function Expression
     -->
	<xsl:template match="Function">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="*[1]"/>
			<xsl:text>(</xsl:text>
			<xsl:choose>
				<xsl:when test="local-name(*[2]) = 'Allow'">
					<xsl:apply-templates select="*[2]/@Option"/>
					<xsl:text> </xsl:text>
					<xsl:apply-templates select="*[3]"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:apply-templates select="*[2]"/>
				</xsl:otherwise>
			</xsl:choose>
			<xsl:text>)</xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
     -  Trigonometric Function Expression
     -->
	<xsl:template match="*[@xsi:type = 'ns1:trigonometricFunctionType'] | 
        *[@xsi:type = 'trigonometricFunctionType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="@Name"/>
			<xsl:text>(</xsl:text>
			<xsl:apply-templates select="*"/>
			<xsl:text>)</xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
     -  Math Function Expression
     -->
	<xsl:template match="*[@xsi:type = 'ns1:mathFunctionType'] | 
        *[@xsi:type = 'mathFunctionType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="@Name"/>
			<xsl:text>(</xsl:text>
			<xsl:apply-templates select="*"/>
			<xsl:text>)</xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
     - Aggregate Function Expression
     -->
	<xsl:template match="*[@xsi:type = 'ns1:aggregateFunctionType'] | 
          *[@xsi:type = 'aggregateFunctionType']">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:value-of select="@Name"/>
			<xsl:text>(</xsl:text>
			<xsl:apply-templates select="*"/>
			<xsl:text>)</xsl:text>
		</xsl:if>
	</xsl:template>
	<!--
	-    Literal Values
	-->
	<xsl:template match="Literal">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:choose>
				<xsl:when test="@xsi:type='ns1:integerType'">
					<xsl:value-of select="@Value"/>
				</xsl:when>
				<xsl:when test="@xsi:type='integerType'">
					<xsl:value-of select="@Value"/>
				</xsl:when>
				<xsl:when test="@xsi:type='ns1:realType'">
					<xsl:value-of select="@Value"/>
				</xsl:when>
				<xsl:when test="@xsi:type='realType'">
					<xsl:value-of select="@Value"/>
				</xsl:when>
				<xsl:when test="@xsi:type='ns1:stringType'">
					<xsl:text>'</xsl:text>
					<xsl:value-of select="@Value"/>
					<xsl:text>'</xsl:text>
				</xsl:when>
				<xsl:when test="@xsi:type='stringType'">
					<xsl:text>'</xsl:text>
					<xsl:value-of select="@Value"/>
					<xsl:text>'</xsl:text>
				</xsl:when>
			</xsl:choose>
		</xsl:if>
	</xsl:template>
	<!--
     -  Coordinate Values
     -->
	<xsl:template match="q2:CoordValue">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:variable name="string">
				<xsl:for-each select="q2:Value/q2:double">
					<xsl:value-of select="."/>
					<xsl:text> </xsl:text>
				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 1)"/>
		</xsl:if>
	</xsl:template>
	<xsl:template match="CoordValue">
		<xsl:if test="not(@xsi:nil='true')">
			<xsl:variable name="string">
				<xsl:for-each select="Value/double">
					<xsl:value-of select="."/>
					<xsl:text> </xsl:text>
				</xsl:for-each>
			</xsl:variable>
			<xsl:value-of select="substring($string, 1, string-length($string) - 1)"/>
		</xsl:if>
	</xsl:template>

</xsl:stylesheet>
