[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Grouping help
Hi Rick,
After more tinkering than I thought would be necessary, I came up with this solution: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0"> <xsl:mode on-no-match="shallow-copy"/> <xsl:template match="/root"> <task> <xsl:call-template name="group"> <xsl:with-param name="elements" select="*" as="element(*)+"/> </xsl:call-template> </task> </xsl:template> <xsl:template name="group"> <xsl:param name="elements" as="element(*)*"/> <xsl:variable name="min-level" as="xs:integer?" select="min($elements/@level) => xs:integer()" /> <xsl:variable name="prelim" as="document-node()"> <!-- wrap temporary results in a document node because otherwise there wouldn't be adjacency among the result elements --> <xsl:document> <xsl:for-each-group select="$elements" group-starting-with="*[@level = $min-level]"> <xsl:choose> <!-- remember: the context item is the first item in the current group --> <xsl:when test="exists(@level)"> <xsl:apply-templates select="." mode="nest"/> </xsl:when> <xsl:otherwise> <xsl:apply-templates select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:document> </xsl:variable> <xsl:for-each-group select="$prelim/*" group-adjacent="name()"> <xsl:choose> <xsl:when test="starts-with(current-grouping-key(), 'list')"> <!-- merge the many single-item lists that have been created in the first pass --> <xsl:copy> <xsl:sequence select="current-group()/*"/> </xsl:copy> </xsl:when> <xsl:otherwise> <xsl:sequence select="current-group()"/> </xsl:otherwise> </xsl:choose> </xsl:for-each-group> </xsl:template> <xsl:template match="item[@level = '2']" mode="nest"> <pretopic lbl="{@number}"> <title> <xsl:apply-templates/> </title> <xsl:call-template name="group"> <xsl:with-param name="elements" select="tail(current-group())"/> </xsl:call-template> </pretopic> </xsl:template> <xsl:template match="item" mode="nest"> <xsl:element name="list{@level - 2}"> <xsl:apply-templates select="."/> <xsl:call-template name="group"> <xsl:with-param name="elements" select="tail(current-group())"/> </xsl:call-template> </xsl:element> </xsl:template> <xsl:template match="item"> <xsl:element name="l{@level - 2}item"> <xsl:attribute name="lbl" select="@number"/> <xsl:apply-templates/> </xsl:element> </xsl:template> </xsl:stylesheet> In prose form: 'group' is a recursive template that will apply a grouping to its input elements that starts at the items with the lowest @level. In the initial invocation, it will create pretopic elements from the @level=2 items. In each group, the first element will become the title and the remainder of the group will be the input for a nested call of the 'group' template. For item[@level > 2], it will create <listX> elements, with X = @level - 2. Adjacent item[@level = '3'] elements will result in adjacent list1 elements, each of them having just one l1item child. The same for item[@level = '4']: They will result in list2 elements within a l1item, but each list2 element will only hold a single l2item. In order to merge the single-item result lists, the preliminary output will be grouped again, this time using group-adjacent by the name of the result elements. If the name starts with 'list' (list1, list2, ...), the single-item lists will be merged into a longer list with the same name (list1 etc.) that contains all the l1item (etc.) children of all adjacent single-item lists. This second grouping will leave all other result elements (apart from the lists) unchanged. The recursive grouping using the 'group' template will work for more levels than were present in your input. Gerrit On 22.07.2022 22:06, rick@xxxxxxxxxxxxxx wrote: When I start a new group, I donbt get the rest of the items in the previous group.
Registergericht / Commercial Register: Amtsgericht Leipzig Registernummer / Registration Number: HRB 24930 GeschC$ftsfC<hrer / Managing Directors: Gerrit Imsieke, Svea Jelonek, Thomas Schmidt
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|