xslt / xpath question

Discussion in 'XML' started by Brian Schroeder, Aug 4, 2004.

  1. Hello Group,

    I'm quite new to xml, xpath and xslt so I hope I've not overlooked a
    resource where the answer to my question is.

    I'll try to give a short example, but in XML everything gets bloated
    really fast.

    I've got the following situation:

    === a.xml ===
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <n categorie="A">
    <n categorie="B">
    <n categorie="C"/>
    </n>
    <n categorie="D"/>
    </n>
    ===

    I want to transform this via xslt to the following

    A
    A->B
    A->B->C
    A->D

    I came up with the following stylesheet

    === test.xsl ===
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="n">
    <xsl:value-of select="ancestor::*[@categorie]/attribute::categorie"/>
    -&gt; <xsl:value-of select="@categorie"/><xsl:text>
    </xsl:text>
    <xsl:apply-templates select="n"/>
    </xsl:template>
    </xsl:stylesheet>
    ===

    I guess, that "ancestor::*[@categorie]/attribute::categorie" should select
    all ancestor, having an attribute categorie, and from those nodes the
    attribute. My problem is, that only the first attribute "A" will result
    from this question. It seems, that I have to concatenate the values, but
    concat did not help.

    I would really appreciate help and even more pointers to some online
    resource where I can learn about this kind of things. (So far, the best I
    found were the w3 recommendations. Most of the other stuff seemed quite
    useless.)

    Thanks a lot,

    Brian

    --
    Brian Schröder
    http://www.brian-schroeder.de/
     
    Brian Schroeder, Aug 4, 2004
    #1
    1. Advertising

  2. > <xsl:value-of select="ancestor::*[@categorie]/attribute::categorie"/>
    > -&gt; <xsl:value-of select="@categorie"/><xsl:text>


    You should try this instead :

    <xsl:for-each select="ancestor::*[@categorie]">
    <xsl:value-of select="@categorie" /><xsl:text>-&gt;</xsl:text>
    </xsl:for-each>

    Hth

    --
    Rémi Peyronnet
     
    =?ISO-8859-15?Q?R=E9mi_Peyronnet?=, Aug 4, 2004
    #2
    1. Advertising

  3. On Wed, 04 Aug 2004 20:39:04 +0200, Rémi Peyronnet wrote:

    >> <xsl:value-of
    >> select="ancestor::*[@categorie]/attribute::categorie"/> -&gt;
    >> <xsl:value-of select="@categorie"/><xsl:text>

    >
    > You should try this instead :
    >
    > <xsl:for-each select="ancestor::*[@categorie]">
    > <xsl:value-of select="@categorie" /><xsl:text>-&gt;</xsl:text>
    > </xsl:for-each>
    >
    > Hth


    Indeed, you helped a lot. Seems like I have been searching in the wrong
    direction. Quite interesting that xslt needs a looping construct for
    joining a list of results. I would have thought something more
    data-centric more in the spirit of a data transformation language.

    Thank you a lot,

    Brian

    --
    Brian Schröder
    http://www.brian-schroeder.de/
     
    Brian Schroeder, Aug 4, 2004
    #3
  4. Brian Schroeder <> writes:
    > I've got the following situation:
    >
    > === a.xml ===
    > <?xml version="1.0" encoding="ISO-8859-1"?>
    > <n categorie="A">
    > <n categorie="B">
    > <n categorie="C"/>
    > </n>
    > <n categorie="D"/>
    > </n>
    > ===
    >
    > I want to transform this via xslt to the following
    >
    > A
    > A->B
    > A->B->C
    > A->D


    Further to your other replies, rather than use the ancestor axis this
    kind of thing is generally done more naturally in XSLT with recursion.

    This stylesheet (I know it doesn't look more elegant at first sight,
    but recursion is much nicer, honestly) produces the output you desire:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:eek:utput method="text"/>

    <xsl:template match="/">
    <xsl:apply-templates select="n"/>
    </xsl:template>

    <xsl:template match="n">

    <xsl:param name="prefix"/>

    <!-- update the prefix -->
    <xsl:variable name="current">
    <xsl:choose>
    <xsl:when test="$prefix">
    <xsl:value-of select="concat($prefix,'->',@categorie)"/>
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:value-of select="@categorie"/>
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:variable>

    <!-- output the new prefix -->
    <xsl:value-of disable-output-escaping="yes" select="$current"/>
    <xsl:text>
    </xsl:text> <!-- a newline -->

    <!-- recursively treat my child-nodes -->
    <xsl:apply-templates select="n">
    <xsl:with-param name="prefix">
    <xsl:value-of select="$current"/>
    </xsl:with-param>
    </xsl:apply-templates>

    </xsl:template>

    </xsl:stylesheet>

    --
    Ben Edgington
    Mail to the address above is discarded.
    Mail to ben at that address might be read.
    http://www.edginet.org/
     
    Ben Edgington, Aug 5, 2004
    #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. Marvin_123456

    "Memory leak" in javax.xml.xpath.XPath

    Marvin_123456, Jul 29, 2005, in forum: Java
    Replies:
    4
    Views:
    2,028
    jan V
    Jul 29, 2005
  2. Alastair Cameron
    Replies:
    1
    Views:
    7,522
    SQL Server Development Team [MSFT]
    Jul 8, 2003
  3. David Blickstein
    Replies:
    1
    Views:
    392
    Dimitre Novatchev
    Sep 14, 2005
  4. Replies:
    3
    Views:
    21,203
    Martin Honnen
    Oct 4, 2005
  5. =?UTF-8?b?5byg6Z+h5q2m?=

    xslt question: using variable in xpath not allowed?

    =?UTF-8?b?5byg6Z+h5q2m?=, Oct 22, 2006, in forum: XML
    Replies:
    2
    Views:
    815
    Martin Honnen
    Oct 22, 2006
Loading...

Share This Page