At 2005-01-15 21:00 -0700, Daniel O'Donnell wrote:
What I am interested in is sorting and grouping input on two or
three keys. I am building an xml document containing the index for print
book. The index was written in a 4-field spreadsheet. The following shows
some of the allowable permutations:
head-a, subfield1-a, subfield2-a, locater1
head-a, subfield1-b, subfield2-g, locater2
head-a, subfield1-b, subfield2-h, locater3
head-b, subfield1-x, ---, locater4
head-c, ---, ---, ---
It would have helped us to help you if you had given us XML for your data.
What I want to produce is a hierarchical list of the following type:
<list>
<item>head-a
<list>
<item>subfield1-a
<list>
<item>subfield2-a, <seg type="locater">locater1</item>
</list>
</item>
<item>subfield1-b
<list>
<item>subfield2-g, <seg type="locater">locater2</item></item>
<item>subfield2-h, <seg type="locater">locater3</item></item>
</list>
</item>
</list>
</item>
<item>head-b
<list>
<item>subfield1-x, <seg type="locater">locater4</item></item>
</list>
</item>
<item>head-c
</item>
</list>
Your use of mixed content for <item> seems strange ... but I've followed
the example. I've assumed the end tag for seg is the mistyped initial end
tag for item in order for the above to be well-formed.
So what I need is a sheet that does the following:
a) sorts records by head
b) groups records so that if two subfield1's are children of heads with
the same content they are put in the same record
c) repeats the same for subfield2's
This is an example of multi-level grouping.
For those of you who are interested in what I have been doing, I've been
using the "Muench Method"
I far prefer using the variable-based method than the Muenchian method when
doing multi-level grouping. While it can be done using the Muenchian
method, keeping track of the unique id's of common apex points can be a
real pain.
Here are some examples of multi-level grouping that I've posted in the past:
http://www.biglist.com/lists/xsl-list/archives/200401/msg00340.html
http://www.biglist.com/lists/xsl-list/archives/200207/msg01418.html
http://www.biglist.com/lists/xsl-list/archives/200205/msg00487.html
Following those examples, I've coded below a solution to your
problem. Comments in the code show how the variable-based method of
multi-level grouping is done.
I hope this helps.
............................... Ken
T:\ftemp>type daniel1.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<all>
<data><h>head-a</h><s1>subfield1-a</s1><s2>subfield2-a</s2><l>locator1</l></data>
<data><h>head-a</h><s1>subfield1-b</s1><s2>subfield2-g</s2><l>locator2</l></data>
<data><h>head-a</h><s1>subfield1-b</s1><s2>subfield2-h</s2><l>locator3</l></data>
<data><h>head-b</h><s1>subfield1-x</s1><s2>---</s2><l>locator4</l></data>
<data><h>head-c</h><s1>---</s1><s2>---</s2><l>---</l></data>
</all>
T:\ftemp>saxon daniel1.xml daniel.xsl
<?xml version="1.0" encoding="utf-8"?>
<list>
<item>head-a<list>
<item>subfield1-a<list>
<item>subfield2-a, <seg>locator1</seg>
</item>
</list>
</item>
<item>subfield1-b<list>
<item>subfield2-g, <seg>locator2</seg>
</item>
<item>subfield2-h, <seg>locator3</seg>
</item>
</list>
</item>
</list>
</item>
<item>head-b<list>
<item>subfield1-x, <seg>locator4</seg>
</item>
</list>
</item>
<item>head-c</item>
</list>
T:\ftemp>type daniel.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="recs" select="/all/data"/>
<list>
<!--walk through all records-->
<xsl:for-each select="$recs">
<xsl:if test="generate-id(.)=
generate-id($recs[h=current()/h])">
<!--found unique headings-->
<item>
<xsl:value-of select="h"/>
<!--do all for the given heading-->
<xsl:call-template name="heads">
<xsl:with-param name="recs" select="$recs"/>
</xsl:call-template>
</item>
</xsl:if>
</xsl:for-each>
</list>
</xsl:template>
<xsl:template name="heads">
<xsl:param name="recs"/>
<xsl:variable name="heads" select="$recs[h=current()/h]"/>
<xsl:choose>
<xsl:when test="$heads[s1='---']">
<!--no more grouping once hit this signal-->
<xsl:if test="l!='---'">
<xsl:text/>, <seg><xsl:value-of select="l"/></seg>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<list>
<!--walk through all of given heading-->
<xsl:for-each select="$heads">
<xsl:if test="generate-id(.)=
generate-id($heads[s1=current()/s1])">
<!--found unique s1-->
<item>
<xsl:value-of select="s1"/>
<!--do all for the given s1-->
<xsl:call-template name="s1">
<xsl:with-param name="recs" select="$recs"/>
</xsl:call-template>
</item>
</xsl:if>
</xsl:for-each>
</list>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="s1">
<xsl:param name="recs"/>
<xsl:variable name="s1s" select="$recs[s1=current()/s1]"/>
<xsl:choose>
<xsl:when test="$s1s[s2='---']">
<!--no more grouping once hit this signal-->
<xsl:if test="l!='---'">
<xsl:text/>, <seg><xsl:value-of select="l"/></seg>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<list>
<!--walk through all of given s1s-->
<xsl:for-each select="$s1s">
<xsl:if test="generate-id(.)=
generate-id($s1s[s2=current()/s2])">
<!--found unique s2-->
<item>
<xsl:value-of select="s2"/>
<!--do all for the given s2-->
<xsl:call-template name="s2">
<xsl:with-param name="recs" select="$recs"/>
</xsl:call-template>
</item>
</xsl:if>
</xsl:for-each>
</list>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="s2">
<xsl:param name="recs"/>
<xsl:variable name="s2s" select="$recs[s2=current()/s2]"/>
<xsl:choose>
<xsl:when test="$s2s[s2='---'] or count($s2s)=1">
<!--no more grouping once hit this signal-->
<xsl:if test="l!='---'">
<xsl:text/>, <seg><xsl:value-of select="l"/></seg>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<!--multiple locations for a given combination of head, s1, s2-->
<xsl:text>
</xsl:text>
<list>
<xsl:for-each select="$s2s">
<xsl:if test="generate-id(.)=
generate-id($s2s[l=current()/l])">
<item>
<xsl:text/>, <seg><xsl:value-of select="l"/></seg>
</item>
</xsl:if>
</xsl:for-each>
</list>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
T:\ftemp>rem Done!
--
World-wide on-site corporate, govt. & user group XML/XSL training.
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)
Male Breast Cancer Awareness http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers: http://www.CraneSoftwrights.com/legal
--~------------------------------------------------------------------
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>
--~--