Keys: Reorganizing definition list based on attribute

Eslam 007

New Member
I posted a question about keys yesterday, and got very helpful responses. I've been working on the last detail in this particular file set most of today; there must just be something I'm missing when it comes to the proper use of keys.I have the following definition list:\[code\]<dl><dlentry><dt>BLARG a</dt><dd>BLARG Definition b</dd></dlentry><dlentry><dt outputclass="values">Value c<ph> Value Description d</ph></dt><dd/></dlentry><dlentry><dt outputclass="values">Value e<ph> Value Description f</ph></dt><dd/></dlentry><dlentry><dt outputclass="values">Value g<ph> Value Description h</ph></dt><dd/></dlentry><dlentry><dt>BLARG2 i</dt><dd>BLARG2 Description j</dd></dlentry><dlentry><dt outputclass="values">Value k<ph>Value description l</ph></dt><dd/></dlentry><dlentry><dt outputclass="values">Value m <ph>Value description n</ph></dt><dd/></dlentry><dlentry> <dt outputclass="values">Value o <ph>Value description p</ph></dt><dd/></dlentry><dlentry><dt>BLARG3 q</dt><dd>BLARG3 Definition r</dd></dlentry></dl>\[/code\]Here is my transformation (that doesn't quite work -- I had it closer than this earlier today, but managed to make it worse):\[code\]<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"><xsl:key name="kFollowing" match="dlentry[child::dt/@outputclass='values']" use="generate-id(preceding-sibling::dlentry[not(child::dt/@outputclass='values')])"/><!-- identity template --><xsl:template match="@*|node()" name="identity"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy></xsl:template><xsl:template match="dd[../following-sibling::dlentry[1]/dt[@outputclass='values']]"> <xsl:variable name="vFollowing" select="key('kFollowing',generate-id(..))"/> <dd><xsl:value-of select="."/> <table> <tgroup cols="2"> <colspec colnum="1" colname="col1" colwidth="*"/> <colspec colnum="2" colname="col2" colwidth="*"/> <tbody> <xsl:for-each select="../following-sibling::dlentry[key('kFollowing',$vFollowing)]"> <row> <entry colname="1"> <xsl:value-of select="./dt/text()"/> </entry> <entry colname="2"> <xsl:apply-templates select="./dt/ph/text()"></xsl:apply-templates> </entry> </row> </xsl:for-each> </tbody> </tgroup> </table></dd></xsl:template></xsl:stylesheet>\[/code\]And my desired output:\[code\]<dl><dlentry> <dt>BLARG a</dt> <dd>BLARG Definition b <table> <tgroup cols="2"> <colspec colnum="1" colname="col1" colwidth="*"/> <colspec colnum="2" colname="col2" colwidth="*"/> <tbody> <row> <entry colname="1">Value c</entry> <entry colname="2">Value Description d</entry> </row> <row> <entry colname="1">Value e</entry> <entry colname="2">Value Description f</entry> </row> <row> <entry colname="1">Value g</entry> <entry colname="2">Value Description h</entry> </row> </tbody> </tgroup> </table></dd></dlentry><dlentry> <dt>BLARG2 i</dt> <dd>BLARG2 Definition j <table> <tgroup cols="2"> <colspec colnum="1" colname="col1" colwidth="*"/> <colspec colnum="2" colname="col2" colwidth="*"/> <tbody> <row> <entry colname="1">Value k</entry> <entry colname="2">Value Description l</entry> </row> <row> <entry colname="1">Value m</entry> <entry colname="2">Value Description n</entry> </row> <row> <entry colname="1">Value o</entry> <entry colname="2">Value Description p</entry> </row> </tbody> </tgroup> </table></dd></dlentry><dlentry><dt>BLARG3 q</dt> <dd>BLARG3 Definition r<dd></dlentry></dl>\[/code\]Grouping rules (Sean's edit) nodes are grouped on nodes which do NOT have a dt[outputclass="values"] child, AND all following sibling nodes which DO have a dt[outputclass="values"] child.The transformation of nodes are thus grouped. Note that if the group has only one member in it (that is to say no dlentry s with a dt[outputclass="values"], then the table output as shown in the sample output document is to be suppressed.
 
Back
Top