FW: [xsl] Searching the last element

Subject: FW: [xsl] Searching the last element
From: TSchutzerWeissmann@xxxxxxxxxxxxxxxx
Date: Fri, 25 Apr 2003 14:36:12 +0100

Hi Andreas,

If you have this

<xsl:template match="text">
	<!-- do something or other -->
	<xsl:apply-templates/>
</xsl:template>

then you're applying templates to everything inside <text>. This includes
attributes, text nodes, comments as well as children.

That means that the set of nodes to which templates are being applied when
your <p> template matches, doesn't just include <p> nodes. It probably
contains text nodes with whitespace in as well. If the last of these node is
a text node, then position() = last() will always be false for a <p> node.
You can test this by removing all the spaces and newlines from your input
xml, as this will get rid of the text nodes.

You can either make sure that templates are only applied to <p>s in this
situation, or instead of doing "position() = last()" for your test, test if
the current <p> has any following-sibling <p>s. If it doesn't then it must
be the last one.

So:
<xsl:template match="text">
	<!-- do something or other -->
	<xsl:apply-templates select="p"/>   --- and use the position() test
</xsl:template>

or

<xsl:template match="p">
<p><apply-templates/>
<xsl:if test="not(following-sibling::p)"> * </xsl:if>
</p>
</xsl:template>

HTH
Tom SW
> -----Original Message-----
> From: Andreas Grytz [mailto:agrytz@xxxxxxxxxxxxx]
> Sent: 25 April 2003 12:20
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: [xsl] Searching the last element
> 
> 
> On Fri, Apr 25, 2003 at 11:59:50AM +0100, 
> TSchutzerWeissmann@xxxxxxxxxxxxxxxx wrote:
> > Hi Andreas
> > 
> > > > >   <p><xsl:apply-templates/>
> > > > > 	<xsl:if test="/text/p[position()=last()]">
> > > > 
> > > > This tests if there is a last "p" in the whole document and 
> > > will return true every time. You want
> > > > 
> > > >   <xsl:if test="position() = last()">
> > > > 
> > > I am sorry, this solution didn't work. But thanks for 
> explaining me,
> > > what has been wrong with my example.
> > 
> > it's only going to work if you do <xsl:apply-templates 
> select="p"/> in
> > <text> context. 
> > 
> I usually do things like this:
> 
> <xsl:template match="p">
>  <p><xsl:apply-templates/></p>
> </xsl:template>
> 
> Because the Input-Tree might have some elements within the p-element.
> 
> > If you just do <xsl:apply-templates/> you're applying 
> templates to the whole
> > document, which will change the values of position() and 
> last(). They'll
> > only give the values you want if you're just applying 
> templates to this set
> > of <p>s
> Wasn't this clear, when I wrote <xsl:template match="p">?
> 
> BTW, if I change my stylesheet to:
> 
> <xsl:template match="p">
>  <p><xsl:apply-templates select="p"/></p>
> </xsl:template>
> 
> I got only starting <p>. Anyway, I am stumbling through the fog with a
> little light in front.
> 
> Thanks,
> 
> 	Andreas
> 
> > 
> > HTH
> > Tom SW
> > 
> >  XSL-List info and archive:  
http://www.mulberrytech.com/xsl/xsl-list

-- 
Andreas Grytz		| http://www.linuxnewmedia.de
Stefan-George-Ring 24	| Tel:	+49 (0) 89 993411-0
D-81929 München		| Fax:	+49 (0) 89 993411-99

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread