Re: [xsl] merging generic elements in a parent-child relationship

Subject: Re: [xsl] merging generic elements in a parent-child relationship
From: Joerg Heinicke <joerg.heinicke@xxxxxx>
Date: Tue, 25 Jun 2002 23:23:17 +0200
Hello Matias,

the following stylesheet will do the job:

The key indexes als <b/> and <c/> by their @ida and @idb attribute values. This key is later used to access the "childs".

The key('abc', @id) with this <xsl:key/> means
<xsl:apply-templates select="(../b|../c)[@ida = current()/@id or @idb = current()/@id]"/>


<xsl:key name="abc" match="b|c" use="@ida|@idb"/>

<xsl:template match="root">
  <xsl:copy>
    <xsl:apply-templates select="a"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="a|b|c">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="key('abc', @id)"/>
  </xsl:copy>
</xsl:template>

Of course using the key is a bit more readable and normally much faster (dependent on the file size).
Furthermore you can use a more validating version to avoid or at least ignore errors in writing XML. The following changed key-declaration for example ignores @ida on c-elements.


<xsl:key name="abc" match="b" use="@ida"/>
<xsl:key name="abc" match="c" use="@idb"/>

Regards,

Joerg

Matias Woloski wrote:
Hi!
I have this xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
	<a id="abc"/>
	<a id="abcd"/>
	<b id="b1" ida="abc"/>
	<b id="b2" ida="abc"/>
	<b id="b3" ida="abcd"/>
	<c id="c1" idb="b1"/>
</root>

this structure describes a parent-child relationship between a-b and b-c. So
I want to reformat this xml to get this

<?xml version="1.0" encoding="UTF-8"?>
<root>
	<a id="abc">
		<b id="b1" ida="abc">
			<c id="c1" idb="b1"/>
		</b>
		<b id="b2" ida="abc"/>
	</a>
	<a id="abcd">
		<b id="b3" ida="abcd"/>
	</a>
</root>

This seems to be simple but here are the complications
1. the name of the elements to be related (a,b,c) must be generic. This
means I would like to pass them via <xsl:param>. Something like a comma
separated string
for instance, I would pass to the stylesheet this parameter: a,b,c.
2. This can go to n levels. I could have a child for <c> and a child of the
child of <c>, and so on.
   n = quantity of elements which has the comma separated param (3 in this
case).

I thought about using xsl:key in some generic way, but cannot get to the
solution. It's much more difficult than my level of xslt knowledge.

Anyway, help would be appreciated!

Matias



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list





XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread