RE: [xsl] Merging and sorting multiple XML files

Subject: RE: [xsl] Merging and sorting multiple XML files
From: Herve Dubreuil <hervedub@xxxxxxxxx>
Date: Thu, 29 Jul 2004 05:04:17 -0700 (PDT)
Hi,
I've managed to implement correctly the code you gave me and it works
great.
The problem is I have to merge a LOT of files (around 60-70).
The script I have now can merge 2 files at a time.
Well, I could recursively merge them or increase the number of
document() call in the file.

But, is there a way to provide a list and merge all those file at once
like:

list.xml:
<listoffile>
  <wave filename="1.xml">
  <wave filename="2.xml">
  <wave filename="3.xml">
......
  <wave filename="50.xml">
</listoffile>

sample of #.xml

<?xml version="1.0"?>
<PreVCD>
	<component name="stack">
		<subpath path="stack_environment">
			<subpath path="test">
				<variable var="ins" symbol="!" wireonbus="1"/>
			</subpath>
		</subpath>
	</component>
	<dump>
		<time t="5">
			<symbol sign="!" value="0"/>
		</time>
		<time t="10">
			<symbol sign="!" value="1"/>
		</time>
		<time t="25">
			<symbol sign="!" value="0"/>
		</time>
	</dump>
</PreVCD>



Here is the XSL I'm currently using

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"
encoding="UTF-8"/>
		
<xsl:param name="file2" />
<xsl:variable name="doc2" select="document($file2,/*)" />

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

<xsl:template match="PreVCD">
	<xsl:copy>
		<xsl:apply-templates select="component" />
		<xsl:apply-templates select="dump" />
	</xsl:copy>
</xsl:template>

<xsl:template match="component">
	<xsl:copy>
		<xsl:copy-of select="@*" /> 
		<xsl:apply-templates select="subpath |
$doc2/PreVCD/component/subpath[not(@path = current()/subpath/@path)]">
			<xsl:sort select="@path" data-type="text" order="ascending" />
		</xsl:apply-templates>
	</xsl:copy>
</xsl:template>

<xsl:template match="subpath">
	<xsl:variable name="curPath" select="@path" />
	<xsl:copy>
		<xsl:copy-of select="@*" />
		<xsl:copy-of select="* | $doc2/PreVCD/component/subpath[@path
=$curPath]/*" />
	</xsl:copy>
</xsl:template>

<xsl:template match="dump">
	<xsl:copy>
		<xsl:apply-templates select="time | $doc2/PreVCD/dump/time[not(@t =
current()/time/@t)]" >
			<xsl:sort select="@t" data-type="number" order="ascending" />
		</xsl:apply-templates>
	</xsl:copy>
</xsl:template>

<xsl:template match="time">
	<xsl:variable name="curTime" select="@t" />
	<xsl:copy>
		<xsl:copy-of select="@*" />
		<xsl:copy-of select="* | $doc2/PreVCD/dump/time[@t =$curTime]/*" />
	</xsl:copy>
</xsl:template>

</xsl:stylesheet>

it would be great if I had just to provide the list.xml to the parser
and it would ouput a big xml file with the file merged (and arranged as
before)


I've tried this but couldn't get it to work (said error3: there is no
element)

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

<xsl:template match="listoffile">
	<PreVCD>
		<xsl:apply-templates
select="document(wave/@filename)/PreVCD/component">
			<xsl:sort select="@name" />
			<xsl:sort select="subpath/@path" />
		</xsl:apply-templates>
		<xsl:apply-templates select="document(wave/@filename)/PreVCD/dump">
			<xsl:sort select="time/@t" />
			<xsl:sort select="time/symbol/@sign" />
		</xsl:apply-templates>
	</PreVCD>
</xsl:template>

<xsl:template match="@*|node()">
	<xsl:copy>
		<xsl:copy-of select="@*" />
		<xsl:apply-templates select="@*|node()" />
	</xsl:copy>
</xsl:template>
(and I'm not even sure this xsl would sort things correctly -> merge
the same fields)

Thanks in advance
Herve

Current Thread