|
[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
|

Cart








