This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: tough problem
- To: Evgenii Bazarov <evgeniibazarov at usa dot net>
- Subject: Re: tough problem
- From: Jeni Tennison <Jeni dot Tennison at epistemics dot co dot uk>
- Date: Fri, 19 May 2000 12:14:46 +0100
- Cc: xsl-list at mulberrytech dot com
- Reply-To: xsl-list at mulberrytech dot com
Evg,
>I am trying to produce comma-separated list of text nodes
>from any XML using the following transform:
[snip]
>However I can't get rid of trailing comma.
>I tried the
> <xsl:if test="position()!=1">
>test, however the position() is equal 1 more then once.
The position() is equal to 1 more than once because it is testing whether a
particular node is the first in the node-list that is currently being
looked at. In the default case (where apply-templates moves on to the
children of the current node), the node list is just the children. That
means that position() tells you whether the node is the first *child* of
its parent. Of course, in a case like:
<p>Here is some <em>emphasised</em> text.</p>
The word 'emphasised' is the first child of its parent element (the 'em'
element), so it has position() = 1. [Note it's also the last child of its
parent element, so last() would be true as well.]
So, I may be misunderstanding your problem, in which case it might help if
you gave a sample of the input (and desired output), but the secret is to
use the *descendant* axis rather than the default 'child' axis.
Either of the the following approaches works:
----
<!-- calling a named template to operate on the descendant text -->
<xsl:template match="top">
<doc>
<xsl:call-template name="listText"/>
</doc>
</xsl:template>
<xsl:template name="listText">
<xsl:for-each select="descendant::text()[normalize-space() != '']">
<xsl:if test="position() != 1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space()" />
</xsl:for-each>
</xsl:template>
---- OR ----
<!-- applying templates to descendant text -->
<xsl:template match="top">
<doc>
<xsl:apply-templates select="descendant::text()[normalize-space() !=
'']" />
</doc>
</xsl:template>
<xsl:template match="text()[normalize-space() != '']">
<xsl:if test="position() != 1">
<xsl:text>, </xsl:text>
</xsl:if>
<xsl:value-of select="normalize-space()" />
</xsl:template>
----
I hope this helps.
Cheers,
Jeni
Dr Jeni Tennison
Epistemics Ltd, Strelley Hall, Nottingham, NG8 6PE
Telephone 0115 9061301 • Fax 0115 9061304 • Email
jeni.tennison@epistemics.co.uk
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list