xsl-list
[Top] [All Lists]

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

2019-05-30 10:04:42
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(_at_)mitre(_dot_)org
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> 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

--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--

<Prev in Thread] Current Thread [Next in Thread>