xsl rearrange flat document

hi,

i have document like this

<doc>

<subitem id="1" itemid="1"><v>sub item one</v></subitem>

<subitem id="2" itemid="1"><v>sub item two</v></subitem>

<subitem id="3" itemid="1"><v>sub item three</v></subitem>

<subitem id="4" itemid="2"><v>sub item four</v></subitem>

<item id="1"><txt>item 1</txt></item>

<item id="2"><txt>item 2</txt></item>

</doc>

and i want to the output to be like that

item 1

sub item one

sub item two

sub item three

item two

sub item four

so i write xsl file like hte following

insite the template "/"

<xsl:call-template name="item">
<xsl:with-param name="doc_items" select="doc/item"/>
</xsl:call-template>

the rest of the templates

<xsl:template name="item">
<xsl:param name="doc_items"/>
<xsl:for-each select="$doc_items">
<xsl:value-of select="@id"/>. <xsl:value-of select="txt"/>
<xsl:call-template name="subitems">
<xsl:with-param name="doc_subitems" select="parent::subitem[@itemid='@id']"/>
</xsl:call-template>

the subitem template use something like item template but the problem is this param wasn't passed to the subitem template

so how can i pass a set of nodes

thanks in advance




Answer this question

xsl rearrange flat document

  • Steev

    The parent axis contains at most one node -- the immediate parent.

    Therefore, instead of:

    parent::subitem[@itemid='@id']

    you need to use: preceding-sibling::subitem

    Also, the predicate is incorrect -- no attribute "itemid" has the value of the string "@id".

    So, you'll need to really reference the "id" attribute of the current node, for example in this way:

    current()/@id

    Finally, try to use as much as possible xsl:apply-templates instead of xsl:call-template.

    A short and compact solution to your problem is the following:

    <xsl:stylesheet version="1.0"

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

    <xsl:template match="node()|@*">

    <xsl:copy>

    <xsl:apply-templates select="node()|@*"/>

    </xsl:copy>

    </xsl:template>

    <xsl:template match="item">

    <xsl:copy>

    <xsl:apply-templates select="node()|@*"/>

    <xsl:copy-of select=

    "preceding-sibling::subitem
    [@itemid = current()/@id]
    "/>

    </xsl:copy>

    </xsl:template>

    <xsl:template match="subitem"/>

    </xsl:stylesheet>

    When this transformation is applied against the provided xml document:

    <doc>

    <subitem id="1" itemid="1">

    <v>sub item one</v>

    </subitem>

    <subitem id="2" itemid="1">

    <v>sub item two</v>

    </subitem>

    <subitem id="3" itemid="1">

    <v>sub item three</v>

    </subitem>

    <subitem id="4" itemid="2">

    <v>sub item four</v>

    </subitem>

    <item id="1">

    <txt>item 1</txt>

    </item>

    <item id="2">

    <txt>item 2</txt>

    </item>

    </doc>

    the wanted result is produced:

    <doc>

    <item id="1">

    <txt>item 1</txt>

    <subitem id="1" itemid="1">

    <v>sub item one</v>

    </subitem>

    <subitem id="2" itemid="1">

    <v>sub item two</v>

    </subitem>

    <subitem id="3" itemid="1">

    <v>sub item three</v>

    </subitem>

    </item>

    <item id="2">

    <txt>item 2</txt>

    <subitem id="4" itemid="2">

    <v>sub item four</v>

    </subitem>

    </item>

    </doc>

    Hope this helped.

    Cheers,
    Dimitre Novatchev


  • shizuka.a

    hi,

    thank you very much Dimitre, it worked very well with a little bit of modification to get the result that i want, i had substitute this line

    <xsl:copy-of select=

    "preceding-sibling::subitem
    [@itemid = current()/@id]
    "/>

    </xsl:copy>

    i created other template with param instead of copy-of to set the format which i want , i hope its not a bad practice

    (i'm C# developer and used for recursions in text parsing so that i'm trying to find other solution, i hope to get ride of this habit with xsl) anyway

    i hope if you can guide me to a nice book , or tutorial about xsl

    thanks again



  • OmegaMan

    Hi Shakalama,

    The books I always recommend are Jeni Tennison's "Beginning XSLT" and Michael Kay's "XSLT Programmer's Reference".

    I would recommend looking also at their identically named books on XSLT2.0/XPath 2.0.

    Although Microsoft has no XSLT2.0 Processor of its own at this moment, one can run Saxon.NET in a .NET environment and enjoy all the benefits of XSLT 2.0.

    Cheers,
    Dimitre Novatchev


  • amritpal singh

    thank you

  • xsl rearrange flat document