xsl-list
[Top] [All Lists]

Merging and sorting files from a list

2004-08-23 07:06:18
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


<Prev in Thread] Current Thread [Next in Thread>