Re: [xsl] Ordered union of sequences

Subject: Re: [xsl] Ordered union of sequences
From: "Imsieke, Gerrit, le-tex" <gerrit.imsieke@xxxxxxxxx>
Date: Thu, 08 Apr 2010 16:47:05 +0200
Given this input:

--------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<foo>
  <seq><k/><o/><p/><c/><f/></seq>
  <seq><d/><e/><f/><g/></seq>
  <seq><k/><f/><z/></seq>
  <seq><a/><b/><c/><d/></seq>
</foo>
--------------------------------------

applying this XSLT:

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

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


<xsl:template match="/"> <xsl:apply-templates /> </xsl:template>

  <xsl:template match="foo">
    <xsl:copy>
      <xsl:for-each-group select="seq/*" group-by="name(.)" >
        <xsl:sort select="my:sortkey(.)"/>
        <xsl:element name="{current-grouping-key()}" />
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

<xsl:function name="my:sortkey" as="xs:integer?">
<xsl:param name="input" as="element(*)" />
<xsl:variable name="preceding-siblings" select="$input/../../seq/*[name() = name($input)]/preceding-sibling::*[1]" as="element(*)*" />
<xsl:sequence select="if ($preceding-siblings) then max(for $ps in $preceding-siblings return my:sortkey($ps)) + 1 else 1"/>
</xsl:function>


</xsl:stylesheet>
--------------------------------------

I receive:

--------------------------------------
<foo>
   <k/>
   <a/>
   <o/>
   <b/>
   <p/>
   <c/>
   <d/>
   <e/>
   <f/>
   <g/>
   <z/>
</foo>
--------------------------------------

Does that make sense?

If I include <o/> at the other position, i.e.,
<seq><k/><f/><z/><o/></seq>,
I receive "Too many nested function calls. May be due to infinite recursion." as expected.


Gerrit


On 08.04.2010 16:38, Michael Kay wrote:
There is an arbitrary number of sequences, sometimes
containing items
with the same name:

(k, o, p, c, f)
(d, e, f, g)
(k, f, z, o)
(a, b, c, d)

I want to create a master sequence which contains every item once,
preserving the original order.

Doesn't xsl:for-each-group over combined sequence solves the problem?

No, it puts groups in order of first appearance, which would put f before d.


Regards,

Michael Kay
http://www.saxonica.com/
http://twitter.com/michaelhkay


-- Gerrit Imsieke Geschdftsf|hrer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke@xxxxxxxxx, http://www.le-tex.de

Registergericht / Commercial Register: Amtsgericht Leipzig
Registernummer / Registration Number: HRB 24930

Geschdftsf|hrer: Gerrit Imsieke, Svea Jelonek,
Thomas Schmidt, Dr. Reinhard Vvckler

Current Thread