Re: [xsl] XPath expression that yields the same result as xsl:for-each-group?

Subject: Re: [xsl] XPath expression that yields the same result as xsl:for-each-group?
From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 30 May 2019 15:04:37 -0000
Simple XSLT 1.0 -- closest to the requirements :)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kRowByIdents" match="row" use="concat(ARPT__IDENT,
'+', TRM__IDENT)"/>

 <xsl:variable name="vGroups" select=
  "/*/row[generate-id() = generate-id(key('kRowByIdents',
concat(ARPT__IDENT, '+', TRM__IDENT))[1])]"/>

  <xsl:template match="/*">
    <xsl:for-each select="$vGroups">
       <group>
         <xsl:copy-of select="key('kRowByIdents', concat(ARPT__IDENT,
'+', TRM__IDENT))"/>
       </group>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


Cheers,
Dimitre

On Thu, May 30, 2019 at 5:46 AM Costello, Roger L. costello@xxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Hello XSLT/XPath experts!
>
> My XML document consists of a series of rows.
>
> Each row is identified by the combination of two child elements: ARPT__IDENT and TRM__IDENT.
>
> I want to group the rows. A group consists of those rows with the same ARPT__IDENT and TRM__IDENT.
>
> This XML document:
>
> <Test>
>     <row>
>         <ARPT__IDENT>A</ARPT__IDENT>
>         <TRM__IDENT>X</TRM__IDENT>
>         <Data>Foo</Data>
>     </row>
>     <row>
>         <ARPT__IDENT>A</ARPT__IDENT>
>         <TRM__IDENT>X</TRM__IDENT>
>         <Data>Bar</Data>
>     </row>
>     <row>
>         <ARPT__IDENT>A</ARPT__IDENT>
>         <TRM__IDENT>Y</TRM__IDENT>
>         <Data>Blah</Data>
>     </row>
>     <row>
>         <ARPT__IDENT>A</ARPT__IDENT>
>         <TRM__IDENT>Y</TRM__IDENT>
>         <Data>Plugh</Data>
>     </row>
> </Test>
>
> is to be grouped this way:
>
> <results>
>     <group>
>         <row>
>             <ARPT__IDENT>A</ARPT__IDENT>
>             <TRM__IDENT>X</TRM__IDENT>
>             <Data>Foo</Data>
>         </row>
>         <row>
>             <ARPT__IDENT>A</ARPT__IDENT>
>             <TRM__IDENT>X</TRM__IDENT>
>             <Data>Bar</Data>
>         </row>
>     </group>
>     <group>
>         <row>
>             <ARPT__IDENT>A</ARPT__IDENT>
>             <TRM__IDENT>Y</TRM__IDENT>
>             <Data>Blah</Data>
>         </row>
>         <row>
>             <ARPT__IDENT>A</ARPT__IDENT>
>             <TRM__IDENT>Y</TRM__IDENT>
>             <Data>Plugh</Data>
>         </row>
>     </group>
> </results>
>
> I can use xsl:for-each-group to perform the grouping:
>
> <xsl:template match="Test">
>     <xsl:variable name="rows" select="row" as="element(row)*"/>
>     <results>
>         <xsl:for-each-group select="$rows" group-by="concat(ARPT__IDENT, '|', TRM__IDENT)">
>             <group>
>                 <xsl:sequence select="current-group()" />
>             </group>
>         </xsl:for-each-group>
>     </results>
> </xsl:template>
>
> However, I want to create a variable -- $groups -- which holds the groups and then iterate over the variable:
>
> <results>
>     <xsl:for-each select="$groups">
>         <group>
>             <xsl:sequence select="." />
>         </group>
>     </xsl:for-each>
> </results>
>
> What XPath expression will yield the desired value for $groups?
>
> <xsl:variable name="groups" select="???" />
>
> Is there an XPath 2.0 expression that can be used?
>
> /Roger

Current Thread