[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Sum of identical nodes


Subject: Re: [xsl] Sum of identical nodes
From: "Joris Gillis" <roac@xxxxxxxxxx>
Date: Wed, 20 Jul 2005 11:35:20 +0200

Hi again,

Tempore 08:18:34, die 07/20/2005 AD, hinc in xsl-list@xxxxxxxxxxxxxxxxxxxxxx scripsit Alvin Ng <ngkwangming@xxxxxxxxx>:

Each file in File1 and File2 have few hundreds nodes of <moid></moid>
and <mt></mt>. My biggest hindrance is how to recursively sum up each
node from each nodeset.


Here you have a solution that works in more general cases (example below). At first sight, the code looks rather bloated and unintellegible. I fear those impressions will remain and 'cpu-intense' will join them:p . but at least it works...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>


<xsl:param name="file1" select="/"/>
<xsl:param name="file2" select="document('file2.xml')"/>

<xsl:template match="/">
<xml>
<xsl:apply-templates select="$file1/xml/moid | $file2/xml/moid" mode="merge"/>
</xml>
</xsl:template>


<xsl:template match="moid" mode="merge">
<xsl:variable name="moid1" select="$file1/xml/moid[.=current()]"/>
<xsl:variable name="moid2" select="$file2/xml/moid[.=current()]"/>
<xsl:if test="count($moid1|$moid2)=1 or (count($moid1|$moid2)=2 and count(.|$moid1)=1)">
<xsl:copy-of select="."/>
<xsl:variable name="mt1" select="$moid1/following::mt[preceding::moid[1]=current()]"/>
<xsl:variable name="mt2" select="$moid2/following::mt[preceding::moid[1]=current()]"/>
<xsl:apply-templates select="$mt1 | $mt2" mode="merge">
<xsl:with-param name="mt1" select="$mt1"/>
<xsl:with-param name="mt2" select="$mt2"/>
<xsl:with-param name="moid" select="."/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>


<xsl:template match="mt" mode="merge">
<xsl:param name="moid"/>
<xsl:param name="mt1"/>
<xsl:param name="mt2"/>
<xsl:variable name="cnt" select="count(preceding::*[preceding::moid=$moid]) + 1"/>
<xsl:variable name="thismt1" select="$mt1[$cnt]"/>
<xsl:variable name="thismt2" select="$mt2[$cnt]"/>
<xsl:if test="count($thismt1|$thismt2)=1 or (count($thismt1|$thismt2)=2 and count(.|$thismt1)=1)">
<xsl:copy><xsl:value-of select="sum($thismt1|$thismt2)"/></xsl:copy>
</xsl:if>
</xsl:template>


</xsl:stylesheet>


Example:


File 1:
<xml>
<moid> AAA </moid>
    <mt> 1 </mt>
    <mt> 2 </mt>
<moid> BBB </moid>
    <mt> 2 </mt>
    <mt> 3 </mt>
	<mt> 8 </mt>
<moid> CCC </moid>
    <mt> 4 </mt>
    <mt> 6 </mt>
</xml>

File 2:
<xml>
<moid> BBB </moid>
    <mt> 0 </mt>
    <mt> 0 </mt>
<moid> AAA </moid>
    <mt> 2 </mt>
    <mt> 3 </mt>
	<mt> 10 </mt>
<moid> DDD </moid>
    <mt> 4 </mt>
    <mt> 4 </mt>
</xml>

Output:
<xml>
	<moid> AAA </moid>
	<mt>3</mt>
	<mt>5</mt>
	<mt>10</mt>
	<moid> BBB </moid>
	<mt>2</mt>
	<mt>3</mt>
	<mt>8</mt>
	<moid> CCC </moid>
	<mt>4</mt>
	<mt>6</mt>
	<moid> DDD </moid>
	<mt>4</mt>
	<mt>4</mt>
</xml>


regards, -- Joris Gillis (http://users.telenet.be/root-jg/me.html) "N N1N;N.N8N5N9N1 N:N1N9 ON? N;N,N4N9 ON,N=ON1 N2N3N1N/N=N?ON= N1OO ON,N=O "


Current Thread