Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

XSLT : rearranging XML file

Status
Not open for further replies.

mfrmfr

Programmer
Jul 28, 2006
4
0
0
BE
Hi,

I'm quite new to XSLT thus I do not know yet whether what I want to do is possible or not.

I have an XML file (see sample below) that is split into two main parts
- a set of nodes (called form) that may contain a set of items.
- a set of form_ref nodes that describe a structure. The liknk between the structure and the forms node is made by the refname attribute that match a form name attribute.

What I want to do is to produce a result xml file that presents my form nodes in the same order as the structure.

Here's an exmple of the source XML:

<template>

<structure>
<form_ref refname="A"/>
<form_ref refname="B">
<form_ref refname="B1"/>
<form_ref refname="B2"/>
</form_ref>
</structure>

<form name="B"></form>

<form name="B2">
<item item_name="itemname05" value="aaaa" />
<item item_name="itemname06" value="bbbb" />
</form>

<form name="B1">
<item item_name="itemname04" value="yyyy" />
</form>

<form name="A">
<item item_name="itemname01" value="zzz" />
<item item_name="itemname02" value="qqq" />
<item item_name="itemname03" value="ooo" />
</form>

</template>

Thanks for any idea on how to do that in XSLT.
 
I find the time to construct a solution for this.
[tt]
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="xml" indent="yes" encoding="utf-8" />
<xsl:template match="template">
<xsl:copy>
<xsl:apply-templates select="structure" />
</xsl:copy>
</xsl:template>
<xsl:template match="structure">
<xsl:call-template name="getform">
<xsl:with-param name="baseform" select="form_ref[not(parent::form_ref)]" />
</xsl:call-template>
</xsl:template>
<xsl:template name="getform">
<xsl:param name="baseform" />
<xsl:for-each select="$baseform[position()]">
<form>
<xsl:copy-of select="//form[@name=current()/@refname]/@*|
//form[@name=current()/@refname]/node() />
<xsl:if test="current()/child::form_ref">
<xsl:call-template name="getform">
<xsl:with-param name="baseform" select="current()/child::form_ref" />
</xsl:call-template>
</xsl:if>
</form>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
[/tt]
ps: Solution to any major variation should be searched and done by the op. As I recognize every xslt solution is practically a new experience and there is a big asymetry of easiness to adapt, for skilled at all levels, to find solution before seeing one and after seeing one. To show op's initiative, he/she has to make reasonable effort on variations based on a solution shown.
 
Hi Tsuji,

Thanks for your time helping me. The code works perfectly.

I had made so many different attempts without success; finally, being a total newbee in xslt, I was not even sure such a transformation was possible, hence my post.

Basically, I was often very near the solution in my tests (but I had not seen the <xsl:copy> statement yet).

Thanks again for your help.

mfr.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top