XSLT: recursion (with key?) vs nesting call-template

Discussion in 'XML' started by shaun roe, Sep 28, 2005.

  1. shaun roe

    shaun roe Guest

    I have a document about 4 levels deep and in my XSLT I want to generate
    a unique string ID for each basic element based on its path through the
    hierarchy.

    If I use recursion, I am continually accessing the root element ID, here
    is a typical call:

    <xsl:variable name="fullPath"
    select="concat('p',../../../@id,'_c',../../@id,'_r',../@id,'_s',$slaveID)
    "/>

    I *could* do this by nesting call-templates and passing the current id
    as a parameter. Is this likely to be more or less efficient?

    e.g. starting xml:

    <castle id="0>
    <level id="2">
    <room id="2"/>
    <room id="3"/>
    <room id="4"/>
    </level>
    <level id="3">
    <room id="2"/>
    <room id="3"/>
    <room id="4"/>
    </level>
    </castle>


    so heres an xslt:

    <xsl:template match="castle">
    <xsl:fullPath select="concat('c',@id)"/>
    <thisCastle uid="{$fullPath}"/>
    <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="level">
    <xsl:fullPath select="concat('c',../@id,'_l',@id)"/>
    <thisLevel uid="{$fullPath}"/>
    <xsl:apply-templates/>
    </xsl:template>

    <xsl:template match="room">
    <xsl:fullPath select="concat('c',../../@id,'_l',../@id,'_r',@id)"/>
    <thisRoom uid="{$fullPath}"/>
    <xsl:apply-templates/>
    </xsl:template>

    I'm guessing this is very inefficient, accessing the castle ID for each
    room. is there a better way? I could generate an ID, but would the ID
    reflect the data path it took to get to a particular room?

    cheers

    shaun
     
    shaun roe, Sep 28, 2005
    #1
    1. Advertising

  2. shaun roe wrote:


    > I'm guessing this is very inefficient, accessing the castle ID for each
    > room. is there a better way?


    Well if you know that is the root element then a global variable
    <xsl:variable name="rootId" select="/castle/@id" />
    is all you need, then in your expressions you can use
    $rootId

    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
     
    Martin Honnen, Sep 28, 2005
    #2
    1. Advertising

  3. shaun roe

    shaun roe Guest

    In article <433a9e2e$0$16495$-online.net>,
    Martin Honnen <> wrote:

    > shaun roe wrote:
    >
    >
    > > I'm guessing this is very inefficient, accessing the castle ID for each
    > > room. is there a better way?

    >
    > Well if you know that is the root element then a global variable
    > <xsl:variable name="rootId" select="/castle/@id" />
    > is all you need, then in your expressions you can use
    > $rootId


    True, but accessing the root element multiple times is only the worst
    symptom of my philosophy... each 'parent' Id gets recalled by each of
    its children, each grandparent by both the children and grandchildren
    etc. Maybe this is equally efficient as the nested template-call,
    (passing the id as a parameter to children) if this information is
    somehow cached... I dont know.
     
    shaun roe, Sep 28, 2005
    #3
  4. Re: recursion (with key?) vs nesting call-template

    The following transformation implements all your requirements:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput omit-xml-declaration="yes" indent="yes"/>

    <xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:attribute name="globalId">id<xsl:text/>
    <xsl:number count="*" level="multiple"/>
    </xsl:attribute>
    <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
    </xsl:template>
    </xsl:stylesheet>

    When applied on the source xml provided in your post, the result is:

    <castle globalId="id1" id="0">
    <level globalId="id1.1" id="2">
    <room globalId="id1.1.1" id="2"/>
    <room globalId="id1.1.2" id="3"/>
    <room globalId="id1.1.3" id="4"/>
    </level>
    <level globalId="id1.2" id="3">
    <room globalId="id1.2.1" id="2"/>
    <room globalId="id1.2.2" id="3"/>
    <room globalId="id1.2.3" id="4"/>
    </level>
    </castle>


    Cheers,
    Dimitre Novatchev
    "shaun roe" <> wrote in message
    news:...
    >I have a document about 4 levels deep and in my XSLT I want to generate
    > a unique string ID for each basic element based on its path through the
    > hierarchy.
    >
    > If I use recursion, I am continually accessing the root element ID, here
    > is a typical call:
    >
    > <xsl:variable name="fullPath"
    > select="concat('p',../../../@id,'_c',../../@id,'_r',../@id,'_s',$slaveID)
    > "/>
    >
    > I *could* do this by nesting call-templates and passing the current id
    > as a parameter. Is this likely to be more or less efficient?
    >
    > e.g. starting xml:
    >
    > <castle id="0>
    > <level id="2">
    > <room id="2"/>
    > <room id="3"/>
    > <room id="4"/>
    > </level>
    > <level id="3">
    > <room id="2"/>
    > <room id="3"/>
    > <room id="4"/>
    > </level>
    > </castle>
    >
    >
    > so heres an xslt:
    >
    > <xsl:template match="castle">
    > <xsl:fullPath select="concat('c',@id)"/>
    > <thisCastle uid="{$fullPath}"/>
    > <xsl:apply-templates/>
    > </xsl:template>
    >
    > <xsl:template match="level">
    > <xsl:fullPath select="concat('c',../@id,'_l',@id)"/>
    > <thisLevel uid="{$fullPath}"/>
    > <xsl:apply-templates/>
    > </xsl:template>
    >
    > <xsl:template match="room">
    > <xsl:fullPath select="concat('c',../../@id,'_l',../@id,'_r',@id)"/>
    > <thisRoom uid="{$fullPath}"/>
    > <xsl:apply-templates/>
    > </xsl:template>
    >
    > I'm guessing this is very inefficient, accessing the castle ID for each
    > room. is there a better way? I could generate an ID, but would the ID
    > reflect the data path it took to get to a particular room?
    >
    > cheers
    >
    > shaun
     
    Dimitre Novatchev, Sep 28, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oleg Konovalov

    For-each or recursion in XSLT

    Oleg Konovalov, May 14, 2005, in forum: Java
    Replies:
    1
    Views:
    605
    Danny
    Jun 4, 2005
  2. Replies:
    4
    Views:
    327
    Victor Bazarov
    Apr 10, 2006
  3. M P
    Replies:
    1
    Views:
    478
  4. Trans
    Replies:
    10
    Views:
    305
    Sean O'Halpin
    Sep 16, 2005
  5. Replies:
    8
    Views:
    745
    John Reye
    Apr 26, 2012
Loading...

Share This Page