Subject: Re: [xsl] Muench method for two or three keys? (Sorting and Grouping) From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx> Date: Sun, 16 Jan 2005 09:47:04 -0500 |
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, ---, ---, ---
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>
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
For those of you who are interested in what I have been doing, I've been using the "Muench Method"
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
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: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>
-- World-wide on-site corporate, govt. & user group XML/XSL training. G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx 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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Yes, grouping is possible, Joris Gillis | Thread | [xsl] Many XSLT formatting, Marcos Hercules Sant |
Re: [xsl] Muench method for two or , Joris Gillis | Date | Re: [xsl] Removing entire branches , cactus |
Month |