Hello all!
We met a strange problem with XML transformation.
Let us describe our task first:
We need to generate complex xml based reports which could contains
multiple crosstab parts.
We have next requirements:
1. Each crosstab could contains arbitrary number of rows and columns.
2. Crosstab report can include other crosstabs
3. Position of the crosstab is unknown on design phase (user can
build complex report using already designed blocks. crosstab is
the one of the blocks)
4. The highest level of XSLT is hardcoded so we can't change it for
every report
5. Each block have its own unique ID
6. Several blocks can contain same columns and/or rows
Ours assumptions:
1. Key tags for all crosstabs are standard (<item> - atomic set of
information, <row> - name of the item's row, <col> - name of the
item's col, <val> - value of the item)
2. Combination of the row and the col is unique in scope of the block
3. Source data doesn't cover all the combinations of rows and cols.
So missing items should be interpreted as - or 0
Problem is the next:
First block is generated absolutely correct, all the next blocks contain
only combinations of rows and cols which haven't been met in any of
already generated blocks.
Sample:
We need take this
_____________________________
* | C1 | C2 | Total |
------+-------+------+-------
R1 | 1 | 2 | 3 |
------+-------+------+-------
R2 | 2 | - | 2 |
------+-------+------+-------
Total | 3 | 2 | 5 |
-----------------------------
_____________________________
* | C2 | C3 | Total |
------+-------+------+-------
R2 | 4 | 3 | 7 |
------+-------+------+-------
R3 | 21 | 2 | 23 |
------+-------+------+-------
Total | 25 | 5 | 30 |
-----------------------------
But we take this
_____________________________
* | C1 | C2 | Total |
------+-------+------+-------
R1 | 1 | 2 | 3 |
------+-------+------+-------
R2 | 2 | - | 2 |
------+-------+------+-------
Total | 3 | 2 | 5 |
-----------------------------
________________________
* | C3 | Total |
------+-------+---------
R3 | 4 | 7 |
------+-------+---------
Total | 25 | 5 |
------------------------
Sample XML
<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type='text/xsl' href='1.xsl'?>
<notice>
<pivots>
<pivot>
<item>
<col>C1</col>
<row>R1</row>
<val>1</val>
</item>
<item>
<col>C1</col>
<row>R2</row>
<val>3</val>
</item>
<item>
<col>C2</col>
<row>R1</row>
<val>5</val>
</item>
<item>
<col>C2</col>
<row>R2</row>
<val>2</val>
</item>
</pivot>
<pivot>
<item>
<col>C2</col>
<row>R2</row>
<val>1</val>
</item>
<item>
<col>C2</col>
<row>R3</row>
<val>3</val>
</item>
<item>
<col>C3</col>
<row>R2</row>
<val>2</val>
</item>
</pivot>
</pivots>
</notice>
Sample XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="b" match="row" use="."/>
<xsl:key name="c" match="col" use="."/>
<xsl:template match="/">
<xsl:for-each select="/notice/pivots">
<br/>
<xsl:variable name="inc" select="0" />
<xsl:for-each select="pivot">
<table border="1" cellspacing="0" class="stn">
<tr>
<th>*</th>
<xsl:for-each
select="item/row[generate-id(.)=generate-id(key('b',.)[1])]">
<xsl:sort select="."/>
<xsl:variable name="vrow" select="."/>
<th>
<xsl:value-of select="."/>
</th>
</xsl:for-each>
<th>total</th>
</tr>
<xsl:for-each
select="item/col[generate-id(.)=generate-id(key('c',.)[1])]">
<xsl:sort select="."/>
<xsl:variable name="vcol" select="."/>
<tr>
<th><xsl:value-of select="."/></th>
<xsl:for-each
select="../../item/row[generate-id(.)=generate-id(key('b',.)[1])]">
<xsl:variable name="vrow" select="."/>
<td>
<xsl:if test="not(../../item[col=$vcol and
row=$vrow])">-</xsl:if>
<xsl:if test="../../item[col=$vcol and
row=$vrow]"><xsl:value-of select="../../item[col=$vcol and
row=$vrow]/val"/></xsl:if>
</td>
</xsl:for-each>
<td><xsl:value-of select="sum(../../item[col=$vcol]/val)"/></td>
</tr>
</xsl:for-each>
<tr>
<th>total</th>
<xsl:for-each
select="item/row[generate-id(.)=generate-id(key('b',.)[1])]">
<xsl:sort select="."/>
<xsl:variable name="vrow" select="."/>
<td>
<xsl:value-of select="sum(../../item[row=$vrow]/val)"/>
</td>
</xsl:for-each>
<td><xsl:value-of select="sum(item/val)"/></td>
</tr>
</table>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
--
*/Best regards,
Vitaliy Paykov/*
e-mail: vpay(_at_)isd(_dot_)dp(_dot_)ua
ext: 1120
ICQ: 220022522
*/ISD QA/*
--~------------------------------------------------------------------
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>
--~--