2

I'm using xdmp:xslt-invoke() to transform documents in Marklogic. That works fine but today I faced a problem with using <xsl:for-each-group select="..." group-starting-with="..."> (while using group-adjacent works as expected in other parts of my XSLT)

XML Input

<DOC>
  <AL>
    <TABLEAU FILET="1" FRAME="ALL" ID="L90F6543EAA5E12-EFL">
      <TGROUP COLS="2">
        <COLSPEC COLNAME="COL1" COLNUM="1"/>
        <COLSPEC COLNAME="COL2" COLNUM="2"/>
        <TBODY>
          <ROW>
            <ENTRY ALIGN="CENTER" COLNAME="COL1" COLSEP="1" ROWSEP="1" VALIGN="TOP">
              <AL>
                <MOTREP>Éléments à inclure dans l'assiette</MOTREP>
              </AL>
            </ENTRY>
            <ENTRY ALIGN="CENTER" COLNAME="COL2" COLSEP="1" ROWSEP="1" VALIGN="TOP">
              <AL>
                <MOTREP>Éléments exclus de l'assiette</MOTREP>
              </AL>
            </ENTRY>
          </ROW>
        </TBODY>
      </TGROUP>
    </TABLEAU>
  </AL>
</DOC>

XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  version="2.0">
  
  <xsl:output omit-xml-declaration="yes"/>
  
  <xsl:template match="AL">
    <xsl:variable name="self" as="element()" select="."/>
    <xsl:for-each-group select="node()" group-starting-with="LST | TABLEAU">
      <xsl:choose>
        <xsl:when test="local-name(current-group()[1]) = ('LST', 'TABLEAU')">
          <xsl:apply-templates select="current-group()" mode="#current"/>
        </xsl:when>
        <xsl:otherwise>
          <AL>
            <xsl:apply-templates select="current-group()" mode="#current"/>
          </AL>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:template>
  
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*"/>
    </xsl:copy>
  </xsl:template>
  
</xsl:stylesheet>

XML output with Saxon HE 9.8.0.12

<DOC>
  <AL>
    </AL><TABLEAU FILET="1" FRAME="ALL" ID="L90F6543EAA5E12-EFL">
      <TGROUP COLS="2">
        <COLSPEC COLNAME="COL1" COLNUM="1"/>
        <COLSPEC COLNAME="COL2" COLNUM="2"/>
        <TBODY>
          <ROW>
            <ENTRY ALIGN="CENTER" COLNAME="COL1" COLSEP="1" ROWSEP="1" VALIGN="TOP">
              <AL>
                <MOTREP>Éléments à inclure dans l'assiette</MOTREP>
              </AL>
            </ENTRY>
            <ENTRY ALIGN="CENTER" COLNAME="COL2" COLSEP="1" ROWSEP="1" VALIGN="TOP">
              <AL>
                <MOTREP>Éléments exclus de l'assiette</MOTREP>
              </AL>
            </ENTRY>
          </ROW>
        </TBODY>
      </TGROUP>
    </TABLEAU>
  
</DOC>

XML output with Marklogic 10.0-3 XSLT Processor

<DOC>
  <TABLEAU FRAME="ALL" ID="L90F6543EAA5E12-EFL">
    <TGROUP COLS="2">
      <TBODY>
        <ROW>
          <ENTRY ALIGN="CENTER" COLNAME="COL1" COLSEP="1" ROWSEP="1" VALIGN="TOP">
            <TABLEAU FRAME="ALL" ID="L90F6543EAA5E12-EFL">
              <TGROUP COLS="2">
                <TBODY>
                  <ROW>
                    <ENTRY ALIGN="CENTER" COLNAME="COL1" COLSEP="1" ROWSEP="1" VALIGN="TOP">
                      <AL xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                        <MOTREP>Éléments à inclure dans l'assiette test1</MOTREP>
                      </AL>
                    </ENTRY>
                    <ENTRY ALIGN="CENTER" COLNAME="COL2" COLSEP="1" ROWSEP="1" VALIGN="TOP">
                      <AL xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                        <MOTREP>Éléments exclus de l'assiette</MOTREP>
                      </AL>
                    </ENTRY>
                  </ROW>
                </TBODY>
              </TGROUP>
            </TABLEAU>
          </ENTRY>
          <ENTRY ALIGN="CENTER" COLNAME="COL2" COLSEP="1" ROWSEP="1" VALIGN="TOP">
            <TABLEAU FRAME="ALL" ID="L90F6543EAA5E12-EFL">
              <TGROUP COLS="2">
                <TBODY>
                  <ROW>
                    <ENTRY ALIGN="CENTER" COLNAME="COL1" COLSEP="1" ROWSEP="1" VALIGN="TOP">
                      <AL xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                        <MOTREP>Éléments à inclure dans l'assiette test1</MOTREP>
                      </AL>
                    </ENTRY>
                    <ENTRY ALIGN="CENTER" COLNAME="COL2" COLSEP="1" ROWSEP="1" VALIGN="TOP">
                      <AL xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                        <MOTREP>Éléments exclus de l'assiette</MOTREP>
                      </AL>
                    </ENTRY>
                  </ROW>
                </TBODY>
              </TGROUP>
            </TABLEAU>
          </ENTRY>
        </ROW>
      </TBODY>
    </TGROUP>
  </TABLEAU>
</DOC>

It's really strange to get nested TABLEAU elements in Marklogic output, which duplicates the ENTRY content.

It looks like a bug or am I missing something?

Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
  • 1
    I would recommend creating a MarkLogic Support case with this information and ask for a bug to be created. – Mads Hansen Jan 04 '22 at 18:31
  • The Saxon result also surprises me, or at least, I would expect it only with white space stripping turned on for input processing and indentation turned on for output serialization, I don't see either in the code. Given that the outer `AL` has a white space text node before the `TABLEAU` child element I would the grouping attempt on `` expect to start with a group containing that text node and that way the `xsl:otherwise` branch to create an `AL` result element with that text node as the content. – Martin Honnen Jan 04 '22 at 18:46
  • You're completely right Martin, I made different tests and simplify the test case (I used to check if the AL is empty before adding it in my real code). I update the saxon output here with this empty AL coming from indentation – Matthieu Ricaud-Dussarget Jan 05 '22 at 08:36

1 Answers1

0

It does appear that something is bleeding through and context is getting messed up when you use <xsl:apply-templates select="current-group()"> inside of the xsl:for-each-group.

This does appear to be a bug in which unexpected content is being carried through to the output when using xsl:apply-templates to the current-group().

If you change to xsl:copy-of inside the xsl:when:

<xsl:when test="local-name(current-group()[1]) = ('LST', 'TABLEAU')">
  <xsl:copy-of select="current-group()" />
</xsl:when>

then it isn't producing the extra TABLEAU elements and children.

Mads Hansen
  • 63,927
  • 12
  • 112
  • 147
  • Thanks for the analysis Mads. I actually thought about an error for the current-group() which seams to contains much more nodes than it should. – Matthieu Ricaud-Dussarget Jan 05 '22 at 08:57
  • Thanks for the analysis Mads. I actually thought the `current-group()` was wrong (containing much more nodes than it should). It's really strange that copying the current-group or applying template on it gives a different result (as there's a copy template in the xslt). It looks like the `current-group()` sequence is not the same depending on the operation that is applied ?! – Matthieu Ricaud-Dussarget Jan 05 '22 at 09:03