Subject: Re: [xsl] Conditional Assigining From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Thu, 17 May 2001 14:27:55 +0100 |
Hi Sri, If you post XSLT, then it really helps if the XSLT you post matches the source that you're supposedly using to transform it. So for example: > <xsl:template match="First"> You don't have any elements called 'First' in the XML source that you posted. I assume that in real life this template matches the 'xslTutorial' element, or your 'xslTutorial' element in your source is actually called 'First'. > <xsl:for-each select="Section[parentID='0']"> You don't have any elements called 'Section' in the XML source that you posted - XML is case sensitive. I assume you mean 'section' here. > <xsl:variable name="ID" select="sectionID"/> > <xsl:call-template name="recur"> > <xsl:with-param name="id"> > <xsl:value-of select="sectionID" /> > </xsl:with-param> > <xsl:with-param name="pid"> > <xsl:value-of select="parentID" /> > </xsl:with-param> > <xsl:with-param name="textvalue"> > <xsl:value-of select="text" /> > </xsl:with-param> > </xsl:call-template> You can reduce this to: <xsl:call-template name="recur"> <xsl:with-param name="id" select="sectionID" /> <xsl:with-param name="pid" select="parentID" /> <xsl:with-param name="textvalue" select="text" /> </xsl:call-template> However, since what you're doing here is just passing information in to a template, all of which comes from a particular node, I would suggest that you apply templates to the current node (the 'section' element) in 'recur' mode instead: <xsl:apply-templates select="." mode="recur" /> The template would look like: <xsl:template match="section" mode="recur"> id <xsl:value-of select="sectionID" /> pid <xsl:value-of select="parentID" /> text <xsl:value-of select="text" /> </xsl:template> Also, in the named template that you were using, you have: > <xsl:template name="recur"> > <xsl:param name="id" /> > id <xsl:value-of select="$id"/> > <xsl:param name="pid" /> > pid <xsl:value-of select="$pid"/> > <xsl:param name="textvalue" /> > text <xsl:value-of select="$textvalue"/> > </xsl:template> The xsl:param elements must be the first elements within the template - you can't intersperse them with the result that you want in this way. > <xsl:for-each select="../Section[parentID=$ID]"> > sub > <xsl:variable name="ID" select="sectionID"/> Here, you're binding the variable $ID for the second time within the template - the processor should stop when it sees this, as it's an error to reassign a value to a variable. You should therefore get no output when you try to run this stylesheet. > <xsl:call-template name="recur"> > <xsl:with-param name="id"> > <xsl:value-of select="sectionID" /> > </xsl:with-param> > <xsl:with-param name="pid"> > <xsl:value-of select="parentID" /> > </xsl:with-param> > <xsl:with-param name="textvalue"> > <xsl:value-of select="text" /> > </xsl:with-param> > </xsl:call-template> Similarly here you could use: <xsl:apply-templates select="." mode="recur" /> > <xsl:apply-templates select="child::*/section" /> When you apply templates here, the current node is a section element. You're telling the processor to apply templates to the section elements that are children (within the node tree of the source XML) of the current section element. Since none of the section elements have other section elements nested within them, this does nothing. Using the source XML that you provided, the following two templates: <xsl:template match="xslTutorial"> <xsl:for-each select="section[parentID = 0]"> <xsl:apply-templates select="." mode="recur" /> <xsl:variable name="ID" select="sectionID" /> <xsl:for-each select="../section[parentID = $ID]"> sub <xsl:apply-templates select="." mode="recur" /> </xsl:for-each> </xsl:for-each> </xsl:template> <xsl:template match="section" mode="recur"> id <xsl:value-of select="sectionID" /> pid <xsl:value-of select="parentID" /> text <xsl:value-of select="text" /> </xsl:template> Give the result: id 1 pid 0 text section 1 sub id 3 pid 1 text section 1.1 sub id 4 pid 1 text section 1.2 id 2 pid 0 text section 2 sub id 6 pid 2 text section 2.1 sub id 7 pid 2 text section 2.2 Which I think is what you were after. If you have lots of section elements, you might want to consider using a key to index into them by parentID more quickly, rather than searching through them all each time. Set the key up to match section elements and use the parentID: <xsl:key name="sections" match="section" use="parentID" /> And then rather than using section[parentID = ...], you can use the key() function to get the same thing: <xsl:template match="xslTutorial"> <xsl:for-each select="key('sections', 0)"> <xsl:apply-templates select="." mode="recur" /> <xsl:for-each select="key('sections', sectionID)"> sub <xsl:apply-templates select="." mode="recur" /> </xsl:for-each> </xsl:for-each> </xsl:template> I hope that helps, Jeni --- Jeni Tennison http://www.jenitennison.com/ XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Conditional Assigining, Sri ni | Thread | RE: [xsl] Conditional Assigining, Sri ni |
Re: [xsl] XSL to generate XPaths, Michael Strasser | Date | Re: [xsl] Associating namespace pre, Oliver Becker |
Month |