Subject: Re: [xsl] jumping out of a loop revisited From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Wed, 18 Apr 2001 13:05:59 +0100 |
Hi Tanzila, It looks as though you have some general output that should be created for most of the children of the Grasslands element, and then some specialised output for the LinksForTheGenus and References elements. This is a classic example of where using *push* (letting the source XML drive the process, just applying templates to everything and letting the XSLT processor sort out what to do) is a good strategy. So, first made a template for the normal processing of one of the children of Grasslands: <!-- this template matches any child element of Grasslands --> <xsl:template match="Grasslands/*"> <h3><font color="#00007F"> <i><xsl:value-of select="name()" /></i> </font></h3> <p><font color="#008000"><xsl:value-of select="." /></font></p> </xsl:template> Then make templates for the specialised elements. These need to be given a priority that's more than 0.5, so that they override the general template given above: <!-- this template matches the LinksForTheGenus element --> <xsl:template match="Grasslands/LinksForTheGenus" priority="1"> <h3> <a name="Label0045"></a> <font color="#00007F"><i>Links for the genus:</i></font> </h3> <ul> <!-- iterates over the Link elements within the LinksForTheGenus element --> <xsl:for-each select="Link"> <li><font color="#008000"> <xsl:value-of select="Address" />;
<xsl:text /> <xsl:value-of select="Name" /> </font></li> </xsl:for-each> </ul> </xsl:template> <!-- this template matches the References element --> <xsl:template match="Grasslands/References" priority="1"> <!-- iterates over the Ref elements within the References element --> <xsl:for-each select="Ref"> <font color="#0080000"> <xsl:value-of select="Name" /> <xsl:text>
 </xsl:text> <xsl:value-of select="Year" />;
<xsl:text /> </font> </xsl:for-each> </xsl:template> With these templates in place, all you have to do is tell the processor to apply templates to the elements you're interested in. The processor will automatically find the right template for each element and use it. So within a template that matches the Grasslands element, tell the processor to apply templates to the 4th child element onwards, as long as it actually has some content: <xsl:template match="Grasslands"> <xsl:apply-templates select="*[position() > 3 and text()]" /> </xsl:template> [Aside: a couple of things here - you might find that it's more extensible not to use the position of an element to determine whether it should get processed, but rather filter out the elements that you don't want to have templates applied to by name. I don't know what your source looks like, but usually you should only use the position() of an element if you have repeated elements. The second thing is that the text() test sees whether there are any text nodes within a particular element. That means that it may succeed with: <description> </description> and fail with: <description><b>Blah blah</b></description> Usually, I'd use normalize-space() to see whether an element has any textual content or not, rather than text().] 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 -> |
---|---|---|
[xsl] jumping out of a loop revisit, Tanzila Mohammad | Thread | [xsl] suggestion, Meltem Kogelbauer |
[xsl] XML source with DOCTYPE decla, Zeljko Rajic | Date | RE: [xsl] XML source with DOCTYPE d, Michael Kay |
Month |