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

Subject: Re: [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:24:26 -0000
Message 2/2


<!--======================================================================================-->
  <!--STEP-3-->

<!--======================================================================================-->

  <!--2nd grouping-->
  <xsl:template match="FORMS" mode="step3">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:for-each-group select="*" group-by="tokenize(@choix-codes, ' ')">
        <group-2 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-2>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node() | @*" mode="step3">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" mode="#current"/>
    </xsl:copy>
  </xsl:template>


<!--======================================================================================-->
  <!--STEP-4-->

<!--======================================================================================-->

  <!--3rd grouping-->
  <xsl:template match="FORMS" mode="step4">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:for-each-group select="*" group-by="tokenize(@choix-codes, ' ')">
        <group-3 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:sequence select="current-group()"/>
        </group-3>
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="node() | @*" mode="step4">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" mode="#current"/>
    </xsl:copy>
  </xsl:template>


<!--======================================================================================-->
  <!--STEP-5-->

<!--======================================================================================-->

  <!--Suppression unusefull group-3-->
  <xsl:template match="FORMS/group-3[tokenize(@choix-codes, ' ')[1] !=
@key]"
    mode="step5" priority="1"/>

  <!--keep the good group-3 and filter on its group-2 childrens-->
  <xsl:template match="FORMS/group-3" mode="step5">
    <xsl:variable name="max"
select="max(group-2/@count-choix-codes/xs:integer(.))"/>
    <xsl:apply-templates select="group-2[@count-choix-codes = $max][1]"
mode="#current"/>
  </xsl:template>

  <!--Skip group-2 and filter its group-1 childrens-->
  <xsl:template match="FORMS/group-3/group-2" mode="step5">
    <xsl:variable name="self" select="self::group-2" as="element()"/>
    <GROUP>
      <xsl:for-each select="distinct-values(group-1/GRCHOIX/@CODE)">
        <xsl:variable name="CODE" select="." as="xs:string"/>
        <xsl:apply-templates select="($self/group-1/GRCHOIX[@CODE =
$CODE])[1]" mode="#current"/>
      </xsl:for-each>
    </GROUP>
  </xsl:template>

  <!--Delete temp attributes-->
  <xsl:template match="@choix-codes" mode="step5"/>

  <xsl:template match="node() | @*" mode="step5">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" mode="#current"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Current Thread