[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
My (horrible) XSLT solution Message 1/2 : <?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" version="3.0"> <!--==========================================================--> <!--MAIN--> <!--==========================================================--> <xsl:template match="/"> <xsl:variable name="step" select="." as="document-node()"/> <xsl:variable name="step"> <xsl:document> <xsl:apply-templates select="$step" mode="step1"/> </xsl:document> </xsl:variable> <xsl:variable name="step"> <xsl:document> <xsl:apply-templates select="$step" mode="step2"/> </xsl:document> </xsl:variable> <xsl:variable name="step"> <xsl:document> <xsl:apply-templates select="$step" mode="step3"/> </xsl:document> </xsl:variable> <xsl:variable name="step"> <xsl:document> <xsl:apply-templates select="$step" mode="step4"/> </xsl:document> </xsl:variable> <xsl:variable name="step"> <xsl:document> <xsl:apply-templates select="$step" mode="step5"/> </xsl:document> </xsl:variable> <xsl:sequence select="$step"/> </xsl:template> <!--========================================================================= =============--> <!--STEP-1--> <!--========================================================================= =============--> <!--Adding attribute choix-codes sorting values--> <xsl:template match="GRCHOIX" mode="step1"> <xsl:copy> <xsl:apply-templates select="@*" mode="#current"/> <xsl:attribute name="choix-codes"> <xsl:for-each select="CHOIX/@CODE"> <xsl:sort/> <xsl:value-of select="."/> <xsl:if test="not(position() = last())"> <xsl:text> </xsl:text> </xsl:if> </xsl:for-each> </xsl:attribute> <xsl:apply-templates mode="#current"/> </xsl:copy> </xsl:template> <!--copy template--> <xsl:template match="node() | @*" mode="step1"> <xsl:copy> <xsl:apply-templates select="node() | @*" mode="#current"/> </xsl:copy> </xsl:template> <!--========================================================================= =============--> <!--STEP-2--> <!--========================================================================= =============--> <!--1st grouping--> <xsl:template match="FORMS" mode="step2"> <xsl:copy> <xsl:apply-templates select="@*" mode="#current"/> <xsl:for-each-group select="*" group-by="tokenize(@choix-codes, ' ')"> <group-1 key="{current-grouping-key()}"> <xsl:variable name="choix-codes" as="xs:string*"> <xsl:for-each select="distinct-values(tokenize(string-join(current-group()/@choix-codes, ' '), ' '))"> <xsl:sort/> <xsl:value-of select="."/> </xsl:for-each> </xsl:variable> <xsl:attribute name="choix-codes" select="string-join($choix-codes, ' ')"/> <xsl:attribute name="count-choix-codes" select="count($choix-codes)"/> <xsl:sequence select="current-group()"/> <!--<xsl:apply-templates select="current-group()"/>--> </group-1> </xsl:for-each-group> </xsl:copy> </xsl:template> <!--copy template--> <xsl:template match="node() | @*" mode="step2"> <xsl:copy> <xsl:apply-templates select="node() | @*" mode="#current"/> </xsl:copy> </xsl:template> Le ven. 16 juin 2023 C 13:09, Matthieu Ricaud-Dussarget ricaudm@xxxxxxxxx < xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> a C)crit : > Hi all, > > > > I need to group elements that have at least one common value : > > > > <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 values : choix-1, choix-2 b they > must belong the same group > > * grchoix-2 and grchoix-3 have 2 common values : 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 value 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'm really not sure how to go ahead with such a grouping problem. > > I've tried something that work on my sample but it's probably too > complicated (maybe it doesnt' work all cases) and most of all it has > drastic bad performances ! > > I'm using fro-each-group on multiple values, wich causes all combination > to be executed and make the internal variables huge (from A 8Mo input I get > a 500 Mo size of intermediate step) > > At this point I get without surprise a saxon internal error on my real > (rather big) XML input. > > > > See my (so) bad solution in a next message (I get a message size to > long when I copy it here) > > > I'm pretty sure there's something quite more elegant to do, did you ever > had to do such a grouping ? > > BTW I'm using XSLT 3. > > > > Any suggestion/help appreciated > > > > Cheers, > > > Matthieu Ricaud-Dussarget > > > > > > > XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> > EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3423379> (by > email <>) > -- Matthieu Ricaud-Dussarget +33 6.63.25.95.58
|
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
|