xsl-list
[Top] [All Lists]

Re: [xsl] Alternative to except operator that preserves order?

2012-01-10 02:17:08
2012/1/10 Andrew Welch <andrew(_dot_)j(_dot_)welch(_at_)gmail(_dot_)com>:
On 10 January 2012 07:23, TW <zupftom(_at_)googlemail(_dot_)com> wrote:
I'm processing a sorted sequence of elements, recursively eliminating
elements that have already been processed.  I'm using "except" for
this purpose, but except destroys the order and returns the remaining
elements in document order, so I have to re-sort them every time.  Not
so much of a problem because the sequences are not very large, but I
wondered, whether in general there is a better idiom for preserving
the pre-sorted order in situations like this.  The archive didn't make
me any wiser.

Small, complete runnable code sample demonstrating the problem please.



It's really about the general problem of keeping the order of a
sequence when removing items, not a specific problem.  But here is an
example.  This stylesheet can be applied to itself:


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

  <xsl:template name="dummy">
    <dummy x="a56"/>
    <dummy x="a-3"/>
    <dummy x="d52"/>
    <dummy x="d38"/>
    <dummy x="s21"/>
    <dummy x="b93"/>
    <dummy x="a1"/>
    <dummy x="d6"/>
    <dummy x="s4"/>
    <dummy x="d143"/>
    <dummy x="k89"/>
    <dummy x="s-23"/>
    <dummy x="d-6"/>
  </xsl:template>

  <xsl:template match="/">
    <output>
      <xsl:call-template name="processSequence">
        <xsl:with-param name="elements" select="//dummy" as="element()*"/>
      </xsl:call-template>
    </output>
  </xsl:template>

  <xsl:template name="processSequence">
    <xsl:param name="elements" as="element()*"/>

    <xsl:variable name="elementSubset" as="element()*">
      <xsl:call-template name="selectSomeElements">
        <xsl:with-param name="elements" as="element()*">
          <!-- At this point, the sequence has to be re-sorted every
            time because oder is destroyed by except below -->
          <xsl:perform-sort select="$elements">
            <xsl:sort select="number(substring(@x,2))"/>
          </xsl:perform-sort>
        </xsl:with-param>
      </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="remainingElements"
        select="$elements except $elementSubset"/>

    <xsl:for-each select="$elementSubset">
      Do something
      <xsl:copy-of select="."/>
    </xsl:for-each>

    <xsl:if test="$remainingElements">
      <xsl:call-template name="processSequence">
        <xsl:with-param name="elements" select="$remainingElements"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

  <xsl:template name="selectSomeElements">
    <xsl:param name="elements" as="element()*"/>

    <!-- Bogus selection criterium,
      more complex recursive template oringially -->
    <xsl:sequence select="$elements[position() = (1,3)]"/>
  </xsl:template>

</xsl:stylesheet>

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--