[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
RE: [xsl] About
RE: [xsl] About and
Subject: RE: [xsl] About <xsl:param> and <xsl:with-param> From: Stuart Brown <sbrown@xxxxxxxxxxx> Date: Tue, 5 Nov 2002 12:34:13 -0000 |
Hi Hélder <snip> In the next xsl I want to make that the param "cod" be incremented in each time that the <xsl:for-each> cicle occurs, but it's result is an error: "javax.xml.transform.TransformerException: xsl:with-param is not allowed in this position in the stylesheet!" Why?! Tks <?xml version="1.0" encoding="ISO-8859-1"?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:xalan="http://xml.apache.org/xslt"> <xsl:param name="cod">0</xsl:param> <xsl:output method="html"/> <xsl:template match="/"> <xsl:for-each select=".//Boy"> <xsl:with-param name="cod" select="number($cod+1)"/> <!--make other things--> </xsl:for-each> </xsl:template> </xsl:transform> </snip> There's a few errors here. Firstly, there's the issue of what you're actually trying to do. XSL is a functional not a procedural language and therefore once parameters are set (either globally or locally) they cannot be altered. These, and variables (known as the variable-binding elements), are variables in the mathematical sense that they represent any value, not in the literal sense that they "vary"! You should not think in terms of a for-each being an iteration. Each matching node is processed independantly of the others. Secondly, parameters (and variables) can only be defined at the top level of the stylesheet (as a child of <xsl:stylesheet>) or as a child of <xsl:template>. That is, globally to the whole process or locally to the context of a specific template. The <xsl:with-param> exists not to reassign an existing parameter, but to pass a parameter onto another template (overriding any definition of that parameter within the template) and occurs as a child of <xsl:call-template>. All of this probably doesn't help you that much, but it leads towards what you want to acheive. Instead of viewing the <xsl:for-each> as an iteration with an incrementing parameter, see it as calling another template. If you then pass this template a parameter which is defined in terms of the number of preceding Boy elements, you effectively have the increment you are looking for. Thus: <!-- Do not define the parameter globally --> <xsl:template match="/"> <xsl:for-each select=".//Boy"> <!-- Call the named (not matched) template to handle Boy --> <xsl:call-template name="doBoy"> <!-- Define the parameter in terms of the number of preceding Boys --> <xsl:with-param name="cod" select="count(preceding::Boy)+1"/> <xsl:call-template/> </xsl:for-each> </xsl:template> <!-- Handle Boy --> <xsl:template name="doBoy"> <!-- Blank parameter which will received the passed value --> <xsl:param name="cod"/> <xsl:text>This is Boy number </xsl:text> <xsl:value-of select="$cod"/> </xsl:template> Or in this instance you could also simply define the parameter directly within doBoy: <xsl:template match="/"> <xsl:for-each select=".//Boy"> <!-- Call the named (not matched) template to handle Boy --> <xsl:call-template name="doBoy"/> </xsl:for-each> </xsl:template> <!-- Handle Boy --> <xsl:template name="doBoy"> <!-- Parameter defined here --> <xsl:param name="cod" select="count(preceding::Boy)+1"/> <xsl:text>This is Boy number </xsl:text> <xsl:value-of select="$cod"/> </xsl:template> I think you probably need to read up a bit on XSLTs processing model and the handling of variable-binding elements. See http://www.dpawson.co.uk/xsl/sect2/N8090.html and http://www.dpawson.co.uk/xsl/sect2/N5982.html for starters. Cheers, Stuart XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] About <xsl:param> and <xsl:wi, Hélder Sousa | Thread | Re: [xsl] About <xsl:param> and <xs, David Carlisle |
RE: [xsl] Excel XML tranformation, bryan | Date | Re:[xsl] About <xsl:param> and <xsl, Vasu Chakkera |
Month |
Keywords