Search code examples
groupingxslt-2.0xslt-grouping

XSLT for-each-group from variable does not work


for-each-group from XSLT 2.0 works as expected from a file but not from a variable.

Have this file:
~$ cat test.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <delimiter/>
    <c>A</c><c>B</c>
  <delimiter/>
    <c>C</c>
</root>

Using stylesheet for grouping this file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" version="1.0"
  encoding="UTF-8" indent="yes" omit-xml-declaration="no" />

<xsl:template match="*">

  <!-- variable not used for file test -->
  <xsl:variable name="fields">
    <root>
      <delimiter/>
      <c>A</c><c>B</c>
      <delimiter/>
      <c>C</c>
    </root>
  </xsl:variable>

  <xsl:for-each-group select="*" group-starting-with="delimiter">
    <field>
      <xsl:for-each select="current-group()">
        <xsl:value-of select="self::c"/>
      </xsl:for-each>
    </field>
  </xsl:for-each-group>

</xsl:template>

</xsl:stylesheet>

I get the result I want:

<?xml version="1.0" encoding="UTF-8"?>
<field>AB</field>
<field>C</field>

Trying to group the variable name="fields" with:

<xsl:for-each-group select="$fields/*" group-starting-with="delimiter">

I get the result:

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

Why does for-each-group works on a file but not from a variable?


Solution

  • The variable fields is a document-node(), you can define the type of the variable to be element()

    <xsl:variable name="fields" as="element()">
        <root>
            <delimiter/>
            <c>A</c><c>B</c>
            <delimiter/>
            <c>C</c>
        </root>
    </xsl:variable>