At 2002-11-07 07:21 +0000, Felix Garcia wrote:
I have problems to generate the desired output of an XML using XSL. I want
to group in three levels
...
First I want to group in a first level with the same ID,NUMBER. Inside of
this first group, a second group with a second group with PHONE. And
finally a third group, inside the second group with ACT. I'm not sure if
I'm explainig clear.
Unfortunately your data didn't reflect very much of these groupings, so I
created a larger test set in addition to your set.
This is my XSL, that doesn't work
You don't always have to use the key() function ... an answer below uses
variables, which I find much easier for multi-level sorting.
Looking through the code, you'll see a lot of symmetry of each level using
only a subset of the variable from the previous level.
It gives the precise structure answer you quoted (except of course for
indentation).
I hope this helps.
................ Ken
T:\ftemp>type felix.xml
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
<ROW>
<ID>27835</ID>
<NUMBER>29715</NUMBER>
<PHONE>09876</PHONE>
<ACT>ACT34</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>62784</PHONE>
<ACT>ACT87</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT23</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT111</ACT>
</ROW>
</ROWSET>
T:\ftemp>type felix.xsl
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="rows" select="/ROWSET/ROW"/>
<xsl:for-each select="$rows">
<xsl:sort select="ID"/>
<xsl:if test="generate-id(.)=generate-id($rows[ID=current()/ID and
NUMBER=current()/NUMBER])">
<ID><xsl:value-of select="ID"/></ID>
<NUM><xsl:value-of select="NUMBER"/></NUM>
<xsl:variable name="idnums" select="$rows[ID=current()/ID and
NUMBER=current()/NUMBER]"/>
<xsl:for-each select="$idnums">
<xsl:sort select="PHONE"/>
<xsl:if test="generate-id(.)=
generate-id($idnums[PHONE=current()/PHONE])">
<PHONE_DATA>
<PHONE><xsl:value-of select="PHONE"/></PHONE>
<xsl:variable name="phones"
select="$idnums[PHONE=current()/PHONE]"/>
<xsl:for-each select="$phones">
<xsl:if test="generate-id(.)=
generate-id($phones[ACT=current()/ACT])">
<ACT_DATA>
<ACT><xsl:value-of select="ACT"/></ACT>
</ACT_DATA>
</xsl:if>
</xsl:for-each>
</PHONE_DATA>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
T:\ftemp>saxon felix.xml felix.xsl
<?xml version="1.0" encoding="utf-8"?>
<ID>27835</ID>
<NUM>29715</NUM>
<PHONE_DATA>
<PHONE>09876</PHONE>
<ACT_DATA>
<ACT>ACT34</ACT>
</ACT_DATA>
</PHONE_DATA>
<ID>27835</ID>
<NUM>29716</NUM>
<PHONE_DATA>
<PHONE>3333333</PHONE>
<ACT_DATA>
<ACT>ACT23</ACT>
</ACT_DATA>
<ACT_DATA>
<ACT>ACT111</ACT>
</ACT_DATA>
</PHONE_DATA>
<PHONE_DATA>
<PHONE>62784</PHONE>
<ACT_DATA>
<ACT>ACT87</ACT>
</ACT_DATA>
</PHONE_DATA>
T:\ftemp>type felix2.xml
<?xml version="1.0" encoding="UTF-8"?>
<ROWSET>
<ROW>
<ID>27835</ID>
<NUMBER>29715</NUMBER>
<PHONE>09876</PHONE>
<ACT>ACT34</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>62784</PHONE>
<ACT>ACT87</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT23</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT111</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29715</NUMBER>
<PHONE>09876</PHONE>
<ACT>ACT34</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29715</NUMBER>
<PHONE>09877</PHONE>
<ACT>ACT34</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>62784</PHONE>
<ACT>ACT87</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT23</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT111</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29715</NUMBER>
<PHONE>09876</PHONE>
<ACT>ACT35</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>62784</PHONE>
<ACT>ACT87</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT23</ACT>
</ROW>
<ROW>
<ID>27835</ID>
<NUMBER>29716</NUMBER>
<PHONE>3333333</PHONE>
<ACT>ACT112</ACT>
</ROW>
</ROWSET>
T:\ftemp>saxon felix2.xml felix.xsl
<?xml version="1.0" encoding="utf-8"?>
<ID>27835</ID>
<NUM>29715</NUM>
<PHONE_DATA>
<PHONE>09876</PHONE>
<ACT_DATA>
<ACT>ACT34</ACT>
</ACT_DATA>
<ACT_DATA>
<ACT>ACT35</ACT>
</ACT_DATA>
</PHONE_DATA>
<PHONE_DATA>
<PHONE>09877</PHONE>
<ACT_DATA>
<ACT>ACT34</ACT>
</ACT_DATA>
</PHONE_DATA>
<ID>27835</ID>
<NUM>29716</NUM>
<PHONE_DATA>
<PHONE>3333333</PHONE>
<ACT_DATA>
<ACT>ACT23</ACT>
</ACT_DATA>
<ACT_DATA>
<ACT>ACT111</ACT>
</ACT_DATA>
<ACT_DATA>
<ACT>ACT112</ACT>
</ACT_DATA>
</PHONE_DATA>
<PHONE_DATA>
<PHONE>62784</PHONE>
<ACT_DATA>
<ACT>ACT87</ACT>
</ACT_DATA>
</PHONE_DATA>
T:\ftemp>rem Done!
--
Upcoming hands-on in-depth XSLT/XPath and/or XSL-FO:
- North America: Feb 3 - Feb 7,2003
G. Ken Holman mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
ISBN 0-13-065196-6 Definitive XSLT and XPath
ISBN 0-13-140374-5 Definitive XSL-FO
ISBN 1-894049-08-X Practical Transformation Using XSLT and XPath
ISBN 1-894049-10-1 Practical Formatting Using XSL-FO
Next conference training: 2002-12-08,03-03,06
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list