This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: How to compare values between two different looping tags
- From: "Marrow" <marrow at marrowsoft dot com>
- To: <xsl-list at lists dot mulberrytech dot com>
- Date: Fri, 26 Jul 2002 02:29:03 +0100
- Subject: Re: [xsl] How to compare values between two different looping tags
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi,
Making some assumptions on how you want to process for the sample output:-
1) the element names (C,D & E etc.) are not predictable - but only those
elements that contain non-whitespace text are to be included in the table;
2) that the column names (element names) are to be sorted alphabetically
left-to-right;
3) that only distinct values for each column are to be shown - and these values
are to be sorted numerically ascending;
4) a html table is required (if you need text or xml output it shouldn't be too
much of a problem to modify the code)
NB. If assumption #1 above is incorrect then some other criteria will be
required in the code below - by replacing occurences of the expression
'normalize-space(text())' with the desired criteria.
Something like?...
== XSL ===================================
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<!-- set-up keys for finding distinct names and distinct values within names -->
<xsl:key name="kNamedValues" match="*[normalize-space(text())]" use="name()"/>
<xsl:key name="kDistinctNamedValues" match="*[normalize-space(text())]"
use="concat(name(),'|',.)"/>
<!-- find the distinct columns -->
<xsl:variable name="vColumns" select="//*[normalize-space(text())][generate-id()
= generate-id(key('kNamedValues',name()))]"/>
<xsl:template match="/">
<!-- find the maximum number of rows -->
<xsl:variable name="vMaxRows">
<xsl:for-each select="$vColumns">
<xsl:sort select="count(key('kNamedValues',name())[generate-id() =
generate-id(key('kDistinctNamedValues',concat(name(),'|',.)))])"
data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="count(key('kNamedValues',name())[generate-id() =
generate-id(key('kDistinctNamedValues',concat(name(),'|',.)))])"/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<html>
<body>
<table border="1">
<!-- header row -->
<tr>
<xsl:apply-templates select="$vColumns" mode="header-columns">
<xsl:sort select="name()"/>
</xsl:apply-templates>
</tr>
<!-- dummy apply through all nodes - to get up to max rows -->
<xsl:apply-templates select="(//*)[position() <= $vMaxRows]"
mode="rows"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="*" mode="header-columns">
<th>
<xsl:value-of select="name()"/>
</th>
</xsl:template>
<xsl:template match="*" mode="rows">
<tr>
<xsl:apply-templates select="$vColumns" mode="data-cells">
<xsl:sort select="name()"/>
<xsl:with-param name="rel-posn" select="position()"/>
</xsl:apply-templates>
</tr>
</xsl:template>
<xsl:template match="*" mode="data-cells">
<xsl:param name="rel-posn"/>
<!-- get the distinct values for this named element -->
<xsl:variable name="distinct-values"
select="key('kNamedValues',name())[generate-id() =
generate-id(key('kDistinctNamedValues',concat(name(),'|',.)))]"/>
<!-- find the data for the relative position of these sorted distinct
values -->
<xsl:variable name="this-item">
<xsl:for-each select="$distinct-values">
<xsl:sort data-type="number"/>
<xsl:if test="position() = $rel-posn">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<!-- ouput the column -->
<td align="right">
<!-- decide if data cell exists to be displayed -->
<xsl:choose>
<xsl:when test="normalize-space($this-item)">
<xsl:value-of select="$this-item"/>
</xsl:when>
<xsl:otherwise>
<!-- blank cell -->
<xsl:text>n/a</xsl:text>
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:template>
</xsl:stylesheet>
== end of XSL ==============================
Another alternative would be to use RTFs (Result Tree Fragments) to do some
pre-processing on the data.
Hope this helps
Marrow
http://www.marrowsoft.com - home of Xselerator (XSLT IDE and debugger)
http://www.topxml.com/Xselerator
-----Original Message-----
From: murli bk <bkmurali@hotmail.com>
To: XSL-List@lists.mulberrytech.com <XSL-List@lists.mulberrytech.com>
Date: 25 July 2002 23:33
Subject: [xsl] How to compare values between two different looping tags
>Hi,
>I have an xml file like below.
>
><G>
> <X>
> <A>
> <C>111</C>
> <D>222</D>
> </A>
> <A>
> <C>232</C>
> <D>3232</D>
> </A>
> </X>
>
> <Y>
> <B>
> <C>232</C>
> <E>777</E>
> </B>
> <B>
> <C>111</C>
> <E>000</E>
> </B>
> <B>
> <C>232</C>
> <E>777</E>
> </B>
> </Y>
></G>
>
>How do you write an xsl to get a text output like below?
>
>C D E
>=======================
>111 222 000
>
>232 3232 777
>
>
>Thanks in advance,
>Murali.
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list