RE: [xsl] Passing parameter into xsl:for-each

Subject: RE: [xsl] Passing parameter into xsl:for-each
From: "Andrew Welch" <ajwelch@xxxxxxxxxxxxxxx>
Date: Mon, 16 Aug 2004 16:27:59 +0100
> I have an XML data dictionary which I am trying to use to
> create a SQL DDL statement. The XML is below:
>
> ==============================================================
> ========================
> <?xml version="1.0" encoding="UTF-8"?>
> <dictionary>
> 	<columns>
> 		<column name="COMP_CODE" length="25"/>
> 		<column name="RENW_STOR_PROF_CODE"
> datatype="number" length="10" decimals="2"/>
> 		<column name="ACCSS_AUDIT_DATE" datatype="date"/>
> 		<column name="VAR_LINE_NUM" datatype="number"
> length="5"/>
> 		<column name="VAR_LINE_ROOT_FLAG" length="1"/>
> 	</columns>
> 	<tables>
> 		<table name="M_RENW_STOR_PROF_H" global="Y"
> publish="Y" ui="im_178">
> 			<column name="COMP_CODE" null="N"/>
> 			<column name="RENW_STOR_PROF_CODE" null="N"/>
> 			<index primary="Y">
> 				<column name="COMP_CODE"/>
> 				<column name="RENW_STOR_PROF_CODE"/>
> 			</index>
> 		</table>
> 		<table name="M_RENW_STOR_PROF_D" global="Y"
> publish="Y" ui="im_178">
> 			<column name="COMP_CODE" null="N"/>
> 			<column name="ACCSS_AUDIT_DATE" null="N"/>
> 			<index primary="Y">
> 				<column name="COMP_CODE"/>
> 				<column name="RENW_STOR_PROF_CODE"/>
> 			</index>
> 			<constraint parentTable="M_RENW_STOR_PROF_H"/>
> 		</table>
> 	</tables>
> </dictionary>
> ==============================================================
> ==========================
> I have written the following xsl:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet version="1.0"
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> 	<xsl:template match="/dictionary/tables">
> 		  <xsl:for-each select="table">
> 				<xsl:variable name="tablename"
> select="@name" />
> 				create table
> 				<xsl:value-of select="$tablename"/>
> 				(
> 				<xsl:for-each select="column">
> 					<xsl:variable
> name="columnname" select="@name" />
> 					<colname><xsl:value-of
> select="$columnname"/></colname>
> 					<xsl:call-template
> name="columnDataType">
> 						<xsl:with-param
> name="columnname2" select="$columnname"/>
> 					</xsl:call-template>
>
> 				</xsl:for-each>);
> 		  </xsl:for-each>
> 	</xsl:template>
>
> 	<xsl:template name="columnLength">
> 		<xsl:param name="cname"/>
> 		<name><xsl:value-of select="$cname"/></name>
> 	</xsl:template>
>
> 	<xsl:template name="columnDataType"
> match="/dictionary/columns">
> 		 <xsl:param name="columnname2" />
> 		 <xsl:for-each select="column">
> 			 <name1><xsl:value-of
> select="$columnname2" /></name1>
> 			 <xsl:if test="@name=$columnname2">
> 				 <length><xsl:value-of
> select="@length"/></length>
> 			</xsl:if>
> 		</xsl:for-each>
> 	</xsl:template>
> </xsl:stylesheet>
> ==============================================================
> ===================================
> My problem is that in the columnDataType template, the
> columname2 parameter does not appear to be visible inside the
> xsl:for-each. Is this a known issue or am I doing something wrong?

Your stylesheet is written with an awkward mix of 'push' and 'pull'
processing which means you are having problems with knowing which is the
context node at any one time - I would suggest searching the archive for
push and pull and/or read up on it at the xsl-faq.

The reason why you are getting no content from the columnDataType
template is because the for-each within it iterates over any <column>
children of the context node, which at that point is a <column> node
from the for-each in the /dictionary/tables matching template.  As there
are no column children of each column node, the template does nothing.
You may find stepping through the code with a debugger helps keep track
of which nodes are getting processed.

cheers
andrew

Current Thread