[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] embedded


Subject: Re: [xsl] embedded <xsl-for-each>
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Thu, 21 Feb 2002 14:15:08 +0000

Hi Sébastien,

> i have this template:
>
> <xsl:template match="FLOW-MENU-GRP">
>   <xsl:for-each select="/FLOW-MENU-GRP/FAMILY">
>     <DIV>
>       <xsl:attribute name="ID">
>         <xsl:value-of select="position()"/>
>       </xsl:attribute>
>       <xsl:value-of select="text()"/>
>     </DIV>
>     <xsl:for-each select="/FLOW-MENU-GRP/SERVICE">
>       <DIV>
>         <xsl:attribute name="ID">
>           here i'd like to get the value of position() given above in line 4
>         </xsl:attribute>
>         <xsl:value-of select="text()"/>
>       </DIV>
>     </xsl:for-each>
>   </xsl:for-each>
> </xsl:template>
>
> is this possible using and ancestor path? how should i write it?

It's not possible using the ancestor axis because the SERVICE element
that you're in within the second xsl:for-each is not related in any
way to the FAMILY element that you're processing outside that
xsl:for-each.

Having said that, I'm not sure whether the FAMILY and SERVICE elements
being unrelated is a reflection of the actual XML document that you're
processing, or whether your XPaths are wrong in the above, but either
way, using the ancestor:: axis is a relatively inefficient way of
getting a number, especially if you have the position available to
you...

> is this possible using <xsl:variable>? how should i use it?

You want the variable to be set to the position of the FAMILY element
within the list of FAMILY elements in the document. You need to do that
when the current node is a FAMILY element, which means anywhere within
the outer xsl:for-each. However, you want it to be available within
the inner xsl:for-each, which means that the variable has to be
defined (a) before the inner xsl:for-each and (b) outside the inner
xsl:for-each's preceding siblings. So you could position it in two
places, either:

<xsl:template match="FLOW-MENU-GRP">
  <xsl:for-each select="/FLOW-MENU-GRP/FAMILY">
  
    <xsl:variable name="id" select="position()" />

    <DIV>
      <xsl:attribute name="ID">
        <xsl:value-of select="position()"/>
      </xsl:attribute>
      <xsl:value-of select="text()"/>
    </DIV>
    <xsl:for-each select="/FLOW-MENU-GRP/SERVICE">
      <DIV>
        <xsl:attribute name="ID">
          <xsl:value-of select="$id" />
        </xsl:attribute>
        <xsl:value-of select="text()"/>
      </DIV>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

or:

<xsl:template match="FLOW-MENU-GRP">
  <xsl:for-each select="/FLOW-MENU-GRP/FAMILY">
    <DIV>
      <xsl:attribute name="ID">
        <xsl:value-of select="position()"/>
      </xsl:attribute>
      <xsl:value-of select="text()"/>
    </DIV>

    <xsl:variable name="id" select="position()" />

    <xsl:for-each select="/FLOW-MENU-GRP/SERVICE">
      <DIV>
        <xsl:attribute name="ID">
          <xsl:value-of select="$id" />
        </xsl:attribute>
        <xsl:value-of select="text()"/>
      </DIV>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

I'd usually use the former, especially as it means you can use the
variable when setting the value of the ID attribute for the FAMILY
element as well. I'd also use attribute value templates rather than
xsl:attribute, as it's a lot shorter that way! So:

<xsl:template match="FLOW-MENU-GRP">
  <xsl:for-each select="/FLOW-MENU-GRP/FAMILY">
    <xsl:variable name="id" select="position()" />
    <DIV ID="{$id}">
      <xsl:value-of select="text()"/>
    </DIV>
    <xsl:for-each select="/FLOW-MENU-GRP/SERVICE">
      <DIV ID="{$id}">
        <xsl:value-of select="text()"/>
      </DIV>
    </xsl:for-each>
  </xsl:for-each>
</xsl:template>

[BTW, I'm sure you're aware of this, but having IDs that start with
numbers isn't a good idea (it's illegal in XML), and having two or
more IDs that are exactly the same is probably not a good idea
either.]

I hope that helps,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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



Current Thread
Keywords
xml