Subject: Re: Expression Logic Problem
From: Joerg Heinicke <joerg.heinicke@xxxxxx>
Date: Wed, 31 Jul 2002 20:55:03 +0200
|
Hello Garrel,
self::node()[1] does not work, because self::node() selects the only the
current node --> it's only one, so self::node()[1] is true for every node.
position() does not work (I can only guess, because this part of
stylesheet is missing) because you apply-templates through either
<xsl:apply-templates select="*"/> or <xsl:apply-templates
select="item"/> or <xsl:apply-templates select="node()"/>. So you either
get only once output of 'Snow White' or nothing because text nodes are
counted too.
The solution to your problem is a grouping method, for example using
preceding-sibling axis or Muenchian Grouping.
1. preceding-sibling:
Instead of <xsl:if test="self::node()[1]"> use <xsl:if
test="not(preceding-sibling::field/@id = @id)">
2. Muenchian Grouping:
<!-- this is the grouping key -->
<xsl:key name="fields" match="field" use="@id"/>
<!-- this one is for faster access to resultfields -->
<xsl:key name="resultfields" match="resultfield" use="@id"/>
<xsl:template match="record">
<xsl:apply-templates select="field[generate-id() =
generate-id(key('fields', @id))]" mode="unique"/>
</xsl:template>
<xsl:template match="field" mode="unique">
<xsl:value-of select="key('resultfields', @id)"/>:
<xsl:apply-templates select="key('fields', @id)"/>
</xsl:template>
<xsl:template match="field">
<xsl:value-of select="."/><br/>
</xsl:template>
Furthermore I would remove disable-output-escaping, because you don't
need it and it's not portable: http://www.dpawson.co.uk/xsl/sect2/N2215.html
Regards,
Joerg
Renick, Garrel wrote:
Hello. I'm trying to solve an expression logic problem and I'm stumped.
I'm trying to determine if the context node I'm matching in a
template is the first element. If it is, I want to prepend
some information. If it isn't first, I just want to display the
data. However, it seems as though every element matches my
expression that tries to determine if the element is first.
If someone could help me understand my delimma, I'd greatly
appreciate it. Here is a sample of my data and my template:
My data:
<document>
<configure>
<server>
<resultfield id="100">Snow White</resultfield>
<resultfield id="50">Mickey Mouse</resultfield>
</server>
</configure>
<record>
<field id="100">Snow White and the Seven Dwarfs</field>
<field id="100">A story about some dwarves and their friend</field>
<field id="50">Fantasia</field>
<record>
</document>
My Template:
<xsl:template match="field">
<xsl:variable name="id" select="@id"/>
<xsl:choose>
<!-- when the ID of the resultfield returned by the server matches
the ID of a resultfield to display in the configuration data
and it is the first one, display the resultfield value and precede
it with the display name from the configuration data. If it isn't
first, just display the resultfield value
-->
<xsl:when test="/document/configure/server/resultfield/@id=$id">
<xsl:if test="self::node()[1]">
<!-- I've also tried position()=1 here without success -->
<xsl:value-of select="/document/configure/server/resultfield[@id=$id]"/>:
</xsl:if>
<xsl:value-of disable-output-escaping="yes" select="."/>
<br/>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
The data I expect and want:
Snow White: Snow White and the Seven Dwarfs
A story about some dwarves and their friend
Mickey Mouse: Fantasia
The data I get:
Snow White: Snow White and the Seven Dwarfs
Snow White: A story about some dwarves and their friend
Mickey Mouse: Fantasia
Regards,
Garrel Renick
garrel@xxxxxxxx
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|