Subject: RE: [xsl] Grouping within a group From: "Rick Quatro" <rick@xxxxxxxxxxxxxx> Date: Sun, 11 Aug 2013 08:58:33 -0400 |
Hi Ken, Thank you for your generous help. I am not attached to my original code; I want to learn how to do this the right way, so seeing how you approach it will be very helpful. Thanks again. Rick -----Original Message----- From: G. Ken Holman [mailto:g.ken.holman@xxxxxxxxx] On Behalf Of G. Ken Holman Sent: Saturday, August 10, 2013 10:23 PM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx; xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: Re: [xsl] Grouping within a group At 2013-08-10 21:53 -0400, Rick Quatro wrote: >I have a (basically) flat XML file: >... >With some help from the group, I got a single level of nesting, >starting with each new category. However, I just found out that I need >some sub-grouping. My finished XML needs to look like this: >... >Here is my stylesheet. It gives me what I need, except for the nested ><TeachingPoint> and <SuggestedReading> elements. I am not sure exactly >how to approach this with XSLT 1.0. I have a complete solution below, but I refactored your extensive use of modes and of recursive apply-templates of siblings as I found them very confusing and really unnecessary. In my code below you'll see I use no modes or pushing siblings, and I act on the data in a top-down fashion rather than a sideways fashion. I hope you find this helpful. Perhaps you can just extract what I did for teaching points and suggested readings if you really want to keep the original code, but I suggest you compare the maintainability of the two solutions. . . . . . . . . Ken t:\ftemp>type rick.xml <?xml version="1.0" encoding="UTF-8"?> <Cases> <Story> <Category>Category: Subcategory</Category> <CaseTitle>Title One</CaseTitle> <Institution>Institution One</Institution > <Author>Authors One</Author> <History>History One</History> <DifferentialDiagnosis>Sick</DifferentialDiagnosis> <DifferentialDiagnosis>Sicker</DifferentialDiagnosis> <DifferentialDiagnosis>Sickest</DifferentialDiagnosis> <TeachingPoint>Point1</TeachingPoint> <TeachingPoint>Point2</TeachingPoint> <SuggestedReading>Reading1</SuggestedReading> <SuggestedReading>Reading2</SuggestedReading> <Category>Category One: Subcategory</Category> <CaseTitle>Title Two</CaseTitle> <Institution>Title Two</Institution > <Author>Author Two</Author> <History>History Two</History> <DifferentialDiagnosis>Sickly</DifferentialDiagnosis> <DifferentialDiagnosis>Sicklier</DifferentialDiagnosis> <DifferentialDiagnosis>Sickliest</DifferentialDiagnosis> <TeachingPoint>Point1</TeachingPoint> <TeachingPoint>Point2</TeachingPoint> <SuggestedReading>Reading1</SuggestedReading> <SuggestedReading>Reading2</SuggestedReading></Story> </Cases> t:\ftemp>call xslt rick.xml rick.xsl <?xml version="1.0" encoding="utf-8"?> <data> <newRecord> <Category>Category</Category> <Subcategory>Subcategory</Subcategory> <Case>1</Case> <CaseTitle>Title One</CaseTitle> <Institution>Institution One</Institution> <Author>Authors One</Author> <History>History One</History> <DifferentialDiagnosis1>Sick</DifferentialDiagnosis1> <DifferentialDiagnosis2>Sicker</DifferentialDiagnosis2> <DifferentialDiagnosis3>Sickest</DifferentialDiagnosis3> <TeachingPoints> <TeachingPoint>Point1</TeachingPoint> <TeachingPoint>Point2</TeachingPoint> </TeachingPoints> <SuggestedReadings> <SuggestedReading>Reading1</SuggestedReading> <SuggestedReading>Reading2</SuggestedReading> </SuggestedReadings> </newRecord> <newRecord> <Category>Category One</Category> <Subcategory>Subcategory</Subcategory> <Case>2</Case> <CaseTitle>Title Two</CaseTitle> <Institution>Title Two</Institution> <Author>Author Two</Author> <History>History Two</History> <DifferentialDiagnosis1>Sickly</DifferentialDiagnosis1> <DifferentialDiagnosis2>Sicklier</DifferentialDiagnosis2> <DifferentialDiagnosis3>Sickliest</DifferentialDiagnosis3> <TeachingPoints> <TeachingPoint>Point1</TeachingPoint> <TeachingPoint>Point2</TeachingPoint> </TeachingPoints> <SuggestedReadings> <SuggestedReading>Reading1</SuggestedReading> <SuggestedReading>Reading2</SuggestedReading> </SuggestedReadings> </newRecord> </data> t:\ftemp>type rick.xsl <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="yes" /> <xsl:template match="Cases/Story"> <data> <xsl:apply-templates select="Category" /> </data> </xsl:template> <xsl:key name="category" match="Story/*[not(self::Category)]" use="generate-id(preceding-sibling::Category[1])"/> <xsl:template match="Category"> <newRecord> <Category><xsl:value-of select="substring-before(.,': ')"/></Category> <Subcategory><xsl:value-of select="substring-after(.,': ')"/></Subcategory> <Case><xsl:number count="Category"/></Case> <xsl:apply-templates select="key('category',generate-id(.))"/> </newRecord> </xsl:template> <xsl:template match="Story/*" priority="-1"> <xsl:copy-of select="." /> </xsl:template> <xsl:template match="DifferentialDiagnosis"> <xsl:variable name="diagnosis"> <xsl:value-of select="1 + count(preceding-sibling::DifferentialDiagnosis) - count(preceding-sibling::Category[1]/preceding-sibling::DifferentialDiagnosi s)"/> </xsl:variable> <xsl:element name="{concat(name(),$diagnosis)}"><xsl:value-of select="."/></xsl:element> </xsl:template> <xsl:key name="teaching" match="TeachingPoint" use="generate-id(preceding-sibling::Category[1])"/> <xsl:template match="TeachingPoint"> <xsl:if test="not(preceding-sibling::*[1][self::TeachingPoint])"> <!--now at the first of a set of teaching points--> <TeachingPoints> <xsl:copy-of select="key('teaching', generate-id(preceding-sibling::Category[1]))"/> </TeachingPoints> </xsl:if> </xsl:template> <xsl:key name="suggested" match="SuggestedReading" use="generate-id(preceding-sibling::Category[1])"/> <xsl:template match="SuggestedReading"> <xsl:if test="not(preceding-sibling::*[1][self::SuggestedReading])"> <!--now at the first of a set of suggested readings--> <SuggestedReadings> <xsl:copy-of select="key('suggested', generate-id(preceding-sibling::Category[1]))"/> </SuggestedReadings> </xsl:if> </xsl:template> </xsl:stylesheet> t:\ftemp>rem Done! -- Public XSLT, XSL-FO, and UBL classes in the Netherlands Oct 2013 | Public XSLT, XSL-FO, UBL and code list classes in Australia Oct 2013 | Contact us for world-wide XML consulting and instructor-led training | Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm | Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ | G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx | Google+ profile: https://plus.google.com/116832879756988317389/about | Legal business disclaimers: http://www.CraneSoftwrights.com/legal |
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Grouping within a group, G. Ken Holman | Thread | [xsl] Grouping of text input file l, Wolfgang Laun |
Re: [xsl] Grouping within a group, G. Ken Holman | Date | [xsl] Grouping of text input file l, Wolfgang Laun |
Month |