Re: [xsl] Expression Logic Problem

Subject: Re: [xsl] Expression Logic Problem
From: "Charles Knell" <cknell@xxxxxxxxxx>
Date: Wed, 31 Jul 2002 14:26:02 -0700
Let me recommend Purple Technology's XPath Explorer (http://sourceforge.net/projects/xpe/)

I copied your XML to a file, opened it in XPath Explorer, and determined
this XPath in a few seconds.:
  //record/field/../field[1]

or in expanded form:
  /descendant-or-self::node()/child::record/child::field/parent::node()/child::field[1.0]

This may not be the most efficient XPath, but it is a good starting point.


-- 
Charles Knell
cknell@xxxxxxxxxx - email


---- "Robert S. Koberg" <rob@xxxxxxxxxx> wrote:
> Hi,
> 
> Renick, Garrel wrote:
> > Thanks for replying, Joerg and Robert. I was already 
> > sorting (I didn't show the template that applied my 
> > example template), so your first suggestion worked 
> > flawlessly, Joerg. Your explanations saved my sanity.
> > 
> 
> Here is an example of how to do it a little more simply:
> 
> <xsl:template match="field">
> 
> <!-- check if the current id is the same as the
> 1st-preceding-sibling -->
> 
>     <xsl:if test="not(@id=preceding-sibling::field[1]/@id)">
> 
> <!-- perhaps use a key here? -->
>        <xsl:value-of
>           select="$/document/configure/server/resultfield[@id=$id]"/>
>        <xsl:text>: </xsl:text>
>     </xsl:if>
> 
>     <xsl:apply-templates/>
>     <br/>
> 
> </xsl:template>
> 
>  From Joerg's example:
> 
>  >
>  > 1. preceding-sibling:
>  >
>  > Instead of <xsl:if test="self::node()[1]"> use <xsl:if
>  > test="not(preceding-sibling::field/@id = @id)">
> 
> won't this return the very first field in document order?
> 
> 
> best,
> -Rob
> 
> 
> 
> > Regards,
> > Garrel Renick
> > 
> > -----Original Message-----
> > From: Joerg Heinicke [mailto:joerg.heinicke@xxxxxx]
> > Sent: Wednesday, July 31, 2002 1:55 PM
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: Re: [xsl] Expression Logic Problem
> > 
> > 
> > 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
> > 
> > 
> >  XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
> > 
> 
> 
> 
> 
> 
>  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