[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: Grouping elements that have at least one common va
On 6/16/2023 1:09 PM, Matthieu Ricaud-Dussarget ricaudm@xxxxxxxxx wrote: > > Hi all, > > I need to group elements that have at least one common valueB : > > <FORMS> > > <!--CASE 1--> > > <GRCHOIX CODE="grchoix-1"> > > <CHOIX CODE="choix-1"/> > > <CHOIX CODE="choix-2"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-2"> > > <CHOIX CODE="choix-1"/> > > <CHOIX CODE="choix-2"/> > > <CHOIX CODE="choix-3"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-3"> > > <CHOIX CODE="choix-2"/> > > <CHOIX CODE="choix-3"/> > > <CHOIX CODE="choix-4"/> > > </GRCHOIX> > > <!--CASE 2--> > > <GRCHOIX CODE="grchoix-A"> > > <CHOIX CODE="choix-a"/> > > <CHOIX CODE="choix-b"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-B"> > > <CHOIX CODE="choix-b"/> > > <CHOIX CODE="choix-c"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-C"> > > <CHOIX CODE="choix-d"/> > > <CHOIX CODE="choix-e"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-D"> > > <CHOIX CODE="choix-c"/> > > <CHOIX CODE="choix-d"/> > > </GRCHOIX> > > </FORMS> > > * grchoix-1 and grchoix-2 have 2 common valuesB : choix-1, choix-2 b > they must belong the same group > > * grchoix-2 and grchoix-3 have 2 common valuesB : choix-2, choix-3 b > they must belong the same group > > b At the end : grchoix-1, grchoix-2 and grchoix-3 must belong the same > group > > * grchoix-A and grchoix-B have 1 common valueB choix-b b they must > belong the same group > > * grchoix-B and grchoix-C have 0 common values > > * but as grchoix-D have > > - 1 common value (choix-c) with grchoix-B > > - 1 one common value (choix-d) with grchoix-C > > Then grchoix-B and grchoix-C must also belong the same GROUP > > b At the end : grchoix-A, grchoix-B, grchoix-C and grchoix-D must > belong the same group > > The expected XML output is 2 Groups : > > <FORMS> > > <!--CASE 1--> > > <GROUP> > > <GRCHOIX CODE="grchoix-1"> > > <CHOIX CODE="choix-1"/> > > <CHOIX CODE="choix-2"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-2"> > > <CHOIX CODE="choix-1"/> > > <CHOIX CODE="choix-2"/> > > <CHOIX CODE="choix-3"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-3"> > > <CHOIX CODE="choix-2"/> > > <CHOIX CODE="choix-3"/> > > <CHOIX CODE="choix-4"/> > > </GRCHOIX> > > </GROUP> > > <!--CASE 2--> > > <GROUP> > > <GRCHOIX CODE="grchoix-A"> > > <CHOIX CODE="choix-a"/> > > <CHOIX CODE="choix-b"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-B"> > > <CHOIX CODE="choix-b"/> > > <CHOIX CODE="choix-c"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-C"> > > <CHOIX CODE="choix-d"/> > > <CHOIX CODE="choix-e"/> > > </GRCHOIX> > > <GRCHOIX CODE="grchoix-D"> > > <CHOIX CODE="choix-c"/> > > <CHOIX CODE="choix-d"/> > > </GRCHOIX> > > </GROUP> > > </FORMS> > I think the following XSLT 3 produces the wanted result: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" B B B xmlns:xs="http://www.w3.org/2001/XMLSchema" B B B exclude-result-prefixes="#all" B B B version="3.0"> B <xsl:output method="xml" indent="yes"/> B <xsl:template match="FORMS"> B B B <xsl:copy> B B B B B <xsl:variable name="groups" as="map(xs:untypedAtomic, element(GRCHOIX)*)*"> B B B B B B B <xsl:for-each-group select="GRCHOIX" group-by="CHOIX/@CODE"> B B B B B B B B B <xsl:map-entry key="current-grouping-key()" select="current-group()"/> B B B B B B B </xsl:for-each-group> B B B B B </xsl:variable> B B B B B <xsl:iterate select="$groups"> B B B B B B B <xsl:param name="group" select="()"/> B B B B B B B <xsl:on-completion> B B B B B B B B B <GROUP> B B B B B B B B B B B <xsl:sequence select="$group?*/."/> B B B B B B B B B </GROUP> B B B B B B B </xsl:on-completion> B B B B B B B <xsl:choose> B B B B B B B B B <xsl:when test="empty($group) or $group?*/CHOIX/@CODE = ?*/CHOIX/@CODE"> B B B B B B B B B B B <xsl:next-iteration> B B B B B B B B B B B B B <xsl:with-param name="group" select="$group, ."/> B B B B B B B B B B B </xsl:next-iteration> B B B B B B B B B </xsl:when> B B B B B B B B B <xsl:otherwise> B B B B B B B B B B B <GROUP> B B B B B B B B B B B B B <xsl:sequence select="$group?*/."/> B B B B B B B B B B B </GROUP> B B B B B B B B B B B <xsl:next-iteration> B B B B B B B B B B B B B <xsl:with-param name="group" select="()"/> B B B B B B B B B B B </xsl:next-iteration> B B B B B B B B B </xsl:otherwise> B B B B B B B </xsl:choose> B B B B B </xsl:iterate> B B B </xsl:copy> B </xsl:template> </xsl:stylesheet>
|
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
|