Reputation: 27
Given this kind of structure:
<ROOT>
<MYROW>
<CATEGORYNAME>first</CATEGORYNAME>
<DATA>10</DATA>
</MYROW>
<MYROW>
<CATEGORYNAME>second</CATEGORYNAME>
<DATA>20</DATA>
</MYROW>
<MYROW>
<CATEGORYNAME>second</CATEGORYNAME>
<DATA>30</DATA>
</MYROW>
<MYROW>
<CATEGORYNAME>first</CATEGORYNAME>
<DATA>100</DATA>
</MYROW>
</ROOT>
I am doing this kind of transformation:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="ROOT">
<Worksheet>
<xsl:for-each-group select="MYROW" group-by="CATEGORYNAME">
<ROW>
<CELL>
<DATA>
<xsl:value-of select="current-grouping-key()"/>
</DATA>
</CELL>
</ROW>
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</Worksheet>
</xsl:template>
<xsl:template match="MYROW">
<ROW>
<CELL>
<xsl:value-of select="DATA"/>
</CELL>
</ROW>
</xsl:template>
</xsl:transform>
I would like to compare the "DATA" value with its previous one in the group. I can't manage to get the previous value. I tried:
<xsl:value-of select="preceding-sibling::node()/DATA"/>
which gives all the previous sibling nodes in the original XML and not just in the current group by.
Basically I want to know if there is a way to use xpath within a group-by sequence.
Expected output:
<Worksheet>
<ROW>
<CELL>
<DATA>first</DATA>
</CELL>
</ROW>
<ROW>
<CELL>
<DATA color = "black">10</DATA>
</CELL>
</ROW>
<ROW>
<CELL>
<DATA color = "blue">100</DATA>
</CELL>
</ROW>
<ROW>
<CELL>
<DATA color = "red">5</DATA>
</CELL>
</ROW>
<ROW>
<CELL>
<DATA>second</DATA>
</CELL>
</ROW>
<ROW>
<CELL>
<DATA color = "black">20</DATA>
</CELL>
</ROW>
<ROW>
<CELL>
<DATA color = "blue">30</DATA>
</CELL>
</ROW>
</Worksheet>
Upvotes: 0
Views: 1993
Reputation: 167581
Assuming you have the <xsl:apply-templates select="current-group()"/>
as shown and then a template for the <xsl:template match="MYROW">
then you can use
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:template match="ROOT">
<Worksheet>
<xsl:for-each-group select="MYROW" group-by="CATEGORYNAME">
<ROW>
<CELL>
<DATA>
<xsl:value-of select="current-grouping-key()"/>
</DATA>
</CELL>
</ROW>
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</Worksheet>
</xsl:template>
<xsl:template match="MYROW">
<xsl:variable name="pos" select="position()"/>
<xsl:variable name="preceding-group-member" select="current-group()[$pos - 1]"/>
<xsl:variable name="this-data" select="xs:decimal(DATA)"/>
<xsl:variable name="preceding-data" select="xs:decimal($preceding-group-member/DATA)"/>
<ROW>
<CELL color="{if ($pos eq 1 or $this-data eq $preceding-data)
then 'black' else (if ($this-data gt $preceding-data) then 'blue' else 'red')}">
<xsl:copy-of select="DATA"/>
</CELL>
</ROW>
</xsl:template>
</xsl:transform>
Online at http://xsltransform.net/pPzifp8/1.
Upvotes: 1