xsl-list
[Top] [All Lists]

FW: Searching the last element

2003-04-25 06:36:12


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(_at_)linux-user(_dot_)de]
Sent: 25 April 2003 12:20
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Searching the last element


On Fri, Apr 25, 2003 at 11:59:50AM +0100, 
TSchutzerWeissmann(_at_)uk(_dot_)imshealth(_dot_)com 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



<Prev in Thread] Current Thread [Next in Thread>