[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

Subject: Re: Grouping elements that have at least one common value
From: "Matthieu Ricaud-Dussarget ricaudm@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 16 Jun 2023 11:15:23 -0000
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

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.