xsl-list
[Top] [All Lists]

RE: Merging and sorting multiple XML files

2004-07-27 11:12:24
Here is one solution to your problem.  This is a grouping problem, but since you
are grouping across multiple input documents keys are harder to use than usual.
For that reason, I simply used an Xpath statement to find the first in each
group.  This sample code produces the requested result, but you may want to look
into more optimized code for better performance.  This stylesheet also makes the
assumption that there will not be duplicates within a single document (if this
is false assumption, you will need to change the code or let us know you need
more advice).

Hope this helps.

-Peter

Merge and sort:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="xml" omit-xml-declaration="no" encoding="UTF-8"/>

<xsl:variable name="doc2" select="document('input2.xml')" />

<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="subpath | $doc2/PreVCD/component/subpath"
/>
        </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:copy>
                <xsl:copy-of select="@*" />
                <xsl:apply-templates select="data" />
        </xsl:copy>
</xsl:template>

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

</xsl:stylesheet>


-----Original Message-----
From: Herve Dubreuil [mailto:hervedub(_at_)yahoo(_dot_)com] 
Sent: Tuesday, July 27, 2004 1:03 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Merging and sorting multiple XML files

Hi,
I've been trying all day to do this but I think I'm too much of a newbie...

Here is the thing:
I have multiple xml files that I need to merge and then sort some data in them.

Here is two examples of xml files:

The first one

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

and the second

<?xml version="1.0"?>
<PreVCD>
        <component name="stack">
                <subpath path="stack_behavior">
                        <variable var="i" symbol="@" bussize="1"/>
                </subpath>
        </component>
        <dump>
                <time t="0">
                        <data>
                                <symbol sign="@" value="0"/>
                        </data>
                </time>
                <time t="5">
                        <data>
                                <symbol sign="@" value="1"/>
                        </data>
                </time>
                <time t="10">
                        <data>
                                <symbol sign="@" value="0"/>
                        </data>
                </time>
                <time t="20">
                        <data>
                                <symbol sign="@" value="1"/>
                        </data>
                </time>
        </dump>
</PreVCD>



The ouput should look like:

<PreVCD>
        <component name="stack">
                <subpath path="stack_behavior">
                        <variable var="i" symbol="@" bussize="1"/>
                </subpath>
                <subpath path="stack_environment">
                        <variable var="ins" symbol="!" wireonbus="1"/>
                </subpath>
        </component>
        <dump>
                <time t="0">
                        <data>
                                <symbol sign="@" value="0"/>
                                <symbol sign="!" value="0"/>
                        </data>
                </time>
                <time t="5">
                        <data>
                                <symbol sign="@" value="1"/>
                        </data>
                </time>
                <time t="10">
                        <data>
                                <symbol sign="@" value="0"/>
                                <symbol sign="!" value="1"/>
                        </data>
                </time>
                <time t="20">
                        <data>
                                <symbol sign="@" value="1"/>
                        </data>
                </time>
                <time t="25">
                        <data>
                                <symbol sign="!" value="0"/>
                        </data>
                </time>
        </dump>
</PreVCD>


This means that the node should merge in component and in time and time must be
ordered.

Thanks in advance... this would save my day !! (and night ...)

Herve


--+------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--+--