Hi all,
I've been trying to get this to work for around a week and I can't seem
to find the solution.
I'm parsing a list of file (from list.xml) that have the same
architecture and I want to sort and merge them.
list.xml:
<?xml version="1.0" ?>
<listoffile>
<wave wavepath="1.xml" />
<wave wavepath="2.xml" />
<wave wavepath="3.xml" />
<wave wavepath="4.xml" />
</listoffile>
1.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>
(same for 2.xml, 3.xml etc...)
and I want the output to look like this:
<?xml version="1.0"?>
<PreVCD>
<component name="stack">
<subpath path="stack_environment">
<subpath path="test">
<variable var="ins" symbol="!" wireonbus="1"/>
<variable var="ins" symbol="@" wireonbus="2"/>
</subpath>
<subpath path="stack_behavior">
<subpath path="test2">
<variable var="ins" symbol="#" wireonbus="1"/>
</subpath>
</subpath>
</component>
<dump>
<time t="5">
<symbol sign="!" value="0"/>
<symbol sign="@" value="0"/>
</time>
<time t="10">
<symbol sign="!" value="1"/>
<symbol sign="#" value="0"/>
</time>
<time t="15">
<symbol sign="@" value="1"/>
<symbol sign="#" value="1"/>
</time>
</dump>
</PreVCD>
For this, I created this xslt:
<?xml version="1.0" ?>
<!-- We first start by defining the xsl/xml header -->
<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"/>
<!-- We load into a variable the list of file to parse -->
<xsl:variable name="docs" select="/listoffile/wave"/>
<!-- we select the first file -->
<xsl:template match="listoffile">
<xsl:apply-templates select="wave[1]"/>
</xsl:template>
<xsl:template match="wave">
<xsl:variable name="wavepath" select="@wavepath"/>
<xsl:for-each select="document($wavepath)">
<xsl:apply-templates select="PreVCD"/>
</xsl:for-each>
</xsl:template>
<!--We apply the template component to the node component and the same
to dump -->
<xsl:template match="PreVCD">
<xsl:copy>
<xsl:apply-templates select="component" />
<xsl:apply-templates select="dump" />
</xsl:copy>
</xsl:template>
<!-- In the template component, we copy <component>, then add its
attribute (name) and then copy the subpathes -->
<xsl:template match="component">
<xsl:copy>
<xsl:for-each select="$docs[position() >1]">
<xsl:copy-of
select="document(@wavepath)/PreVCD/component/*" />
<xsl:apply-templates
select="document(@wavepath)/PreVCD/component/subpath |$
docs/PreVCD/component/subpath[not(@path = current()/subpath/@path)]">
<xsl:sort select="@path" data-type="text"
order="ascending" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="subpath">
<xsl:variable name="curPath" select="@path" />
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:copy-of select="* |
$docs/PreVCD/component/subpath[(_at_)path
=$curPath]/*" />
</xsl:copy>
</xsl:template>
<!-- In Dump, we have to regroup elements and sort by time -->
<xsl:template match="dump">
<xsl:copy>
<xsl:for-each select="$docs">
<xsl:apply-templates
select="document(@wavepath)/PreVCD/dump/time |
$docs/PreVCD/dump/time[not(@t = current()/time/@t)]">
<xsl:sort select="@t" data-type="number"
order="ascending" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="time">
<xsl:variable name="curTime" select="@t" />
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:copy-of select="* | $docs/PreVCD/dump/time[(_at_)t
=$curTime]/*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
But I can't get it to work properly. It seems like there is a problem
with the $docs/PreVCD
Here is the output I'm having
<?xml version="1.0" encoding="UTF-8"?>
<PreVCD>
<component>
<subpath path="stack_behavior">
<variable var="i" symbol="@" wireonbus="1"/>
</subpath>
<subpath path="stack_behavior">
<variable var="i" symbol="@" wireonbus="1"/>
</subpath>
<subpath path="stack_environment">
<variable var="ins" symbol="#" wireonbus="2"/>
</subpath>
<subpath path="stack_environment">
<variable var="ins" symbol="#" wireonbus="2"/>
</subpath>
<subpath path="stack_environment">
<variable var="ins" symbol="#" wireonbus="2"/>
</subpath>
<subpath path="stack_environment">
<variable var="ins" symbol="#" wireonbus="2"/>
</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>
<time t="0">
<symbol sign="@" value="0"/>
</time>
<time t="5">
<symbol sign="@" value="1"/>
</time>
<time t="10">
<symbol sign="@" value="0"/>
</time>
<time t="20">
<symbol sign="@" value="1"/>
</time>
<time t="0">
<symbol sign="#" value="0"/>
</time>
<time t="15">
<symbol sign="#" value="1"/>
</time>
<time t="20">
<symbol sign="#" value="0"/>
</time>
<time t="0">
<symbol sign="#" value="0"/>
</time>
<time t="15">
<symbol sign="#" value="1"/>
</time>
<time t="20">
<symbol sign="#" value="0"/>
</time>
</dump>
</PreVCD>
The documents are not entirely merged.....
Thanks in advance if you manage to find the bug!
Herve