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

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