[xsl] Grouping elements that have at least one common value

Subject: [xsl] 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:08:56 -0000
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

Current Thread