Sunday, December 31, 2023

XSLT 3.0 grouping use case

I've just been playing this evening, trying to improve XalanJ prototype processor's XSLT 3.0 xsl:for-each-group instruction's implementation. Following is an xsl:for-each-group instruction use case, that I've been trying to solve.

XML input document,

<?xml version="1.0" encoding="utf-8"?>

<root>

  <a>

    <itm1>hi</itm1>

    <itm2>hello</itm2>

    <itm3>there</itm3>

  </a>

  <b>

    <itm1>this</itm1>

    <itm2>is</itm2>

    <itm3>nice</itm3>

  </b>

  <c>

    <itm1>hello</itm1>

    <itm2>friends</itm2>

  </c>

  <d>

    <itm1>this is ok</itm1>

  </d>

</root>

XSLT 3.0 stylesheet, using xsl:for-each-group instruction to group XML instance elements from an XML document cited above,

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

                         version="3.0">

      <xsl:output method="xml" indent="yes"/>

     <xsl:template match="/root">

           <result>

               <xsl:for-each-group select="*" group-by="(count(*) eq 1) or (count(*) eq 3)">

            <group groupingCriteria="{if (current-grouping-key() eq true()) then '1,3' else 'not(1,3)'}">

                <xsl:copy-of select="current-group()"/>

            </group>

              </xsl:for-each-group>

          </result>

      </xsl:template>

</xsl:stylesheet>

The stylesheet transformation result, of above cited XSLT transform is following as produced by XalanJ,

<?xml version="1.0" encoding="UTF-8"?><result>

  <group groupingCriteria="1,3">

    <a>

    <itm1>hi</itm1>

    <itm2>hello</itm2>

    <itm3>there</itm3>

  </a>

    <b>

    <itm1>this</itm1>

    <itm2>is</itm2>

    <itm3>nice</itm3>

  </b>

    <d>

    <itm1>this is ok</itm1>

  </d>

  </group>

  <group groupingCriteria="not(1,3)">

    <c>

    <itm1>hello</itm1>

    <itm2>friends</itm2>

  </c>

  </group>

</result>

Achieving such XML data grouping, was very hard with XSLT 1.0 language. Thank god, we've XSLT 3.0 language available now.


No comments: