[xsl] numbering nodes in result tree XSLT 2

Subject: [xsl] numbering nodes in result tree XSLT 2
From: "Angela Williams" <Angela.Williams@xxxxxxxxxxxxxxxxxx>
Date: Wed, 8 Aug 2007 15:02:54 -0500
This is yet another faux counter problem. I know I'm making it harder
than it is - and certainly more verbose. I'm not familiar enough with
xsl:number to understand how to use the attributes and have not gleaned
enough information from the references to apply it correctly.

The goal is to merge duplicate notes (except overrides) and update the
references. The first group of notes is numbered appropriately, but
subsequent groups should start over again at 1.

I think I want to group by scope and count the first note with
merge='true' and all notes with merge='false'. I've tried using
position() and xsl:number with various values for level, select, and
count, to no avail.

Any recommendations would be greatly appreciated! Thanks in advance...

Input:
<document>
  <note-block scope-id="A" />
  <note-block scope-id="B" />
  <notes>
    <note ID="1" ref="1" merge="true" scope="A">Some <b>text</b></note>
    <note ID="2" ref="2" merge="false" scope="A">Some <b>text</b></note>
    <note ID="3" ref="1" merge="true" scope="A">More</note>
    <note ID="4" ref="3" merge="true" scope="A">More</note>
    <note ID="5" ref="4" merge="true" scope="B">More</note>
    <note ID="6" ref="1" merge="true" scope="B">More</note>
  </notes>
</document>

Desired Output:
<a>
  <notes>
    <note ref="1" scope="A">Some <b>text</b></note>
    <note-ref ID="1" scope="A" xref="1" />
    <note ref="2" scope="A">Some <b>text</b></note>
    <note-ref ID="2" scope="A" xref="2" />
    <note ref="3" scope="A">More</note>
    <note-ref ID="3" scope="A" xref="3" />
    <note-ref ID="4" scope="A" xref="3" />
  </notes>
  <notes>
    <note ref="1" scope="B">More</note>
    <note-ref ID="5" scope="B" xref="1" />
    <note-ref ID="6" scope="B" xref="1" />
  </notes>
</a>

Actual Output:
<a>
  <notes>
    <note ref="1" scope="A">Some <b>text</b></note>
    <note-ref ID="1" scope="A" xref="1" />
    <note ref="2" scope="A">Some <b>text</b></note>
    <note-ref ID="2" scope="A" xref="2" />
    <note ref="3" scope="A">More</note>
    <note-ref ID="3" scope="A" xref="3" />
    <note-ref ID="4" scope="A" xref="3" />
  </notes>
  <notes>
    <note ref="5" scope="B">More</note>
    <note-ref ID="5" scope="B" xref="5" />
    <note-ref ID="6" scope="B" xref="5" />
  </notes>
</a>

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

  <xsl:template match="document">
    <a>
      <xsl:apply-templates select="note-block" />
    </a>
  </xsl:template>

  <xsl:template match="note-block">

    <xsl:variable name="block-scope" select="string(@scope-id)" />

    <notes>

      <xsl:for-each-group
          select="..//note[string(@scope)=string($block-scope)]"
          group-by=".">

        <!-- Create the common variables for the group -->
        <xsl:variable name="com-ref">
            <xsl:number level="any" />
        </xsl:variable>

        <xsl:variable name="com-nte" select="node()" />

        <!-- Write out the common note -->
        <note ref="{$com-ref}" scope="{$block-scope}">
          <xsl:copy-of select="$com-nte" />
        </note>

        <!-- Process the notes in the group -->
        <xsl:for-each select="current-group()">

          <xsl:choose>
            <xsl:when test="@merge=true()">
              <!--
                   Write out a reference pointing to
                   the common note
               -->
              <note-ref ID="{@ID}" scope="{$block-scope}"
xref="{$com-ref}" />
            </xsl:when>

            <xsl:otherwise>
              <!-- Generate new reference -->
              <xsl:variable name="ref">
                  <xsl:number level="any" />
              </xsl:variable>

              <!--
                  Write out a new note.
               -->
              <note ref="{$ref}" scope="{$block-scope}">
                  <xsl:copy-of select="$com-nte" />
              </note>

              <!--
                  Write out a reference for new note.
               -->
              <note-ref ID="{@ID}" scope="{$block-scope}" xref="{$ref}"
/>
            </xsl:otherwise>
          </xsl:choose>

        </xsl:for-each>

      </xsl:for-each-group>

    </notes>

  </xsl:template>

</xsl:stylesheet>

Thanks!
Angela Williams

Current Thread