Subject: Re: [xsl] Grouping elements that have at least one common value From: "Matthieu Ricaud-Dussarget ricaudm@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Wed, 28 Jun 2023 18:18:33 -0000 |
Hi, I finally got something that works and doesn't take too long. Debugging with xsl:message, I adapted the XSLT to prevent calculating the same thing a lot of time. I come back to "except" which is quite more readable. This is it : <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xf="http://www.lefebvre-sarrut.eu/ns/xmlfirst" xmlns:els="http://www.lefebvre-sarrut.eu/ns/els" xmlns:saxon="http://saxon.sf.net/" exclude-result-prefixes="#all" version="3.0"> <xsl:key name="getGrchoixbyChoixCode" match="GRCHOIX" use="CHOIX/@CODE"/> <xsl:variable name="root" select="/" as="document-node()"/> <xsl:template match="FORMS"> <xsl:copy> <xsl:call-template name="els:process"> <xsl:with-param name="GRCHOIX" as="element()*" select="GRCHOIX"/> </xsl:call-template> </xsl:copy> </xsl:template> <xsl:template name="els:process"> <xsl:param name="GRCHOIX" as="element(GRCHOIX)*"/> <xsl:param name="processed-GRCHOIX" select="()" as="element(GRCHOIX)*"/> <xsl:if test="not(empty($GRCHOIX))"> <xsl:variable name="start-node" select="($GRCHOIX)[1]" as="element(GRCHOIX)"/> <xsl:variable name="start-node.transitive-closure" as="element(GRCHOIX)*" select="els:transitive-closure($start-node)"/> <GROUP GRCHOIX="{distinct-values($start-node.transitive-closure/@CODE)}"> <xsl:sequence select="$start-node.transitive-closure"/> </GROUP> <xsl:variable name="processed-GRCHOIX.local" select="($processed-GRCHOIX, $start-node.transitive-closure)" as="element()*"/> <xsl:call-template name="els:process"> <xsl:with-param name="GRCHOIX" select="$GRCHOIX except $processed-GRCHOIX.local"/> <xsl:with-param name="processed-GRCHOIX" select="$processed-GRCHOIX.local"/> </xsl:call-template> </xsl:if> </xsl:template> <xsl:function name="els:getGrchoixbyChoixCode" as="element(GRCHOIX)*"> <xsl:param name="GRCHOIX" as="element(GRCHOIX)"/> <xsl:sequence select="key('getGrchoixbyChoixCode', $GRCHOIX/CHOIX/@CODE, $root)"/> </xsl:function> <xsl:function name="els:transitive-closure" as="element()*"> <xsl:param name="start-node" as="element()"/> <xsl:iterate select="1 to 100000000"> <xsl:param name="result" as="element()*" select="()"/> <xsl:param name="origins" as="element()*" select="$start-node"/> <xsl:param name="previous-origins" as="element()*" select="()"/> <xsl:variable name="current-iteration.result" as="element()*" select="($origins except $previous-origins) ! els:getGrchoixbyChoixCode(.) except $result"/> <xsl:choose> <xsl:when test="empty($current-iteration.result)"> <xsl:sequence select="$result"/> <xsl:break/> </xsl:when> <xsl:otherwise> <xsl:next-iteration> <xsl:with-param name="result" select="$result | $current-iteration.result"/> <xsl:with-param name="origins" select="$current-iteration.result except $origins"/> <xsl:with-param name="previous-origins" select="$previous-origins | $origins"/> </xsl:next-iteration> </xsl:otherwise> </xsl:choose> </xsl:iterate> </xsl:function> </xsl:stylesheet> Probably not perfect, but I also write a short XSLT to check the result : <?xml version="1.0" encoding="UTF-8"?> <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:key name="getGROUPbyChoixCode" match="GROUP" use="GRCHOIX/CHOIX/@CODE"/> <xsl:template match="/FORMS"> <xsl:copy> <xsl:variable name="self" select="." as="element()"/> <xsl:for-each select="distinct-values(GROUP/GRCHOIX/CHOIX/@CODE)"> <xsl:variable name="CHOIX.CODE" select="."/> <CHOIX CODE="{$CHOIX.CODE}" COUNT-GROUP="{count(key('getGROUPbyChoixCode', $CHOIX.CODE, $self))}"/> </xsl:for-each> </xsl:copy> </xsl:template> </xsl:stylesheet> And yes every CHOIX/@CODE appears in the same GROUP (COUNT-GROUP is always equals to 1) So I'm fine with this :) Thanks again for helping Cheers Matthieu RICAUD-DUSSARGET
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Grouping elements that ha, Matthieu Ricaud-Duss | Thread | [xsl] Table transformation, Dave Pawson dave.paw |
Re: [xsl] Grouping elements that ha, Matthieu Ricaud-Duss | Date | |
Month |