Re: [xsl] Specify/determine element's "logical" parent

Subject: Re: [xsl] Specify/determine element's "logical" parent
From: "john-xsl-list" <john-xsl-list@xxxxxxxx>
Date: Thu, 23 Sep 2004 17:32:29 -0400
Thanks again for the response.  Memory consumption for XML processing in this
environment (something like 4x "file" size) and I'm concerned that creating
these keys every time an XSL is called will be too expensive. 

I don't mean to gripe and I am sorry to bug the list with this, but I seem to
be headed down a very deep and dark path with XSL.  I'm just confusing myself
more the deeper I dig, both surprised and frustrated at how difficult and
complicated it seems for a beginner, and how many of the goals I research
don't seem possible without custom and third-party extensions (dynamic XPath
evaluation, etc.).  I haven't even approached "how to navigate up my logical
hierarchy".  I think I need to take a few weeks off and research XSL but I
have deliverables.  I would be happy to RTFM if I could just find the FM
online, and it's so different from my background that I can't even figure out
what to search for.

For instance, I do not understand the difference between the two templates
listed below, which seem equivalent to me.  The first one fails ("Reference to
variable or parameter 'parent' must evaluate to a node list") while the second
works.  Nor do I understand why when both templates are in a single
stylesheet, only one (the latter?) seems to get applied.  Any help or
suggestions would be appreciated - hopefully I am doing something really
stupid and obvious (at least I got rid of xsl:for-each!).

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:key name="ids" match="item" use="@id"/>

<xsl:template match="/">
  <html>
    <body>
      <xsl:apply-templates select="/*//item"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="item">
  <xsl:if test="../@id">
    <xsl:variable name="parent">
      <xsl:choose>
        <xsl:when test="@parentid">
<!-- following line differs -->
          <xsl:value-of select="key( 'ids', @parentid )" />
        </xsl:when>
        <xsl:otherwise>
<!-- following line differs -->
          <xsl:value-of select="key( 'ids', ../@id )" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
<!-- following line differs -->
    <xsl:value-of select="@id" /> is [<xsl:value-of select="$parent/@id" />]<br />
  </xsl:if>
</xsl:template>

<xsl:template match="item">
  <xsl:if test="../@id">
    <xsl:variable name="parent">
      <xsl:choose>
        <xsl:when test="@parentid">
          <xsl:value-of select="key( 'ids', @parentid )/@id" />
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="key( 'ids', ../@id )/@id" />
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:value-of select="@id" /> is [<xsl:value-of select="$parent" />]<br />
  </xsl:if>
</xsl:template>
</xsl:stylesheet>

<?xml-stylesheet type="text/xsl" href="data.xsl"?>
<items>
  <item id="A1">
    <item id="A2">
      <item id="A3" />
    </item>
  </item>
  <item id="B1">
    <item id="B2">
      <item id="B3" parentid="A2" />
    </item>
  </item>
</items>

Current Thread