Re: [xsl] merging sequences

Subject: Re: [xsl] merging sequences
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 13 Jan 2012 10:48:02 -0500
At 2012-01-13 14:41 +0000, Fabien Tillier wrote:
I have the two following sequences
N112 N100 N107 P2010 N109 P2014 P2015 N108 N203 N206 N307 N311
And
N112 N100 P2014 P2015 N108 N203 N306 N206 N307 N311
...
I would like to align these so that the resulting sequence contains all items, but keeping the order, thus
...
N112 N100 N107 P2010 N109 P2014 P2015 N108 N203 N306 N206 N307 N311

I hope the example below helps. It bases a sort on expressing each item's location in its own sequence and the other sequence.


. . . . . . . . . Ken

T:\ftemp>xslt2 fabien.xsl fabien.xsl
N112,N100,N107,P2010,N109,P2014,P2015,N108,N203,N206,N307,N311
N112,N100,P2014,P2015,N108,N203,N306,N206,N307,N311
N112,N100,N107,P2010,N109,P2014,P2015,N108,N203,N306,N206,N307,N311
T:\ftemp>type fabien.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="2.0">
  <xsl:output method="text"/>

<xsl:template match="/">
<!--input sequences-->
<xsl:variable name="seq1" select="tokenize('N112 N100 N107 P2010 N109 P2014 P2015 N108 N203 N206 N307 N311','\s+')"/>
<xsl:variable name="seq2" select="tokenize('N112 N100 P2014 P2015 N108 N203 N306 N206 N307 N311','\s+')"/>


  <!--order them with information about their position in other sequence-->
  <xsl:variable name="items1">
    <xsl:for-each select="$seq1">
      <item index="{position()}" other="{index-of($seq2,.)[1]}">
        <xsl:value-of select="."/>
      </item>
    </xsl:for-each>
  </xsl:variable>
  <xsl:variable name="items2">
    <xsl:for-each select="$seq2">
      <item index="{position()}" other="{index-of($seq1,.)[1]}">
        <xsl:value-of select="."/>
      </item>
    </xsl:for-each>
  </xsl:variable>

  <!--reveal inputs-->
  <xsl:value-of select="$seq1" separator=","/><xsl:text>&#xa;</xsl:text>
  <xsl:value-of select="$seq2" separator=","/><xsl:text>&#xa;</xsl:text>
  <!--order the result based on relative positions-->
  <xsl:for-each select="$items1/item,$items2/item[@other='']">
    <xsl:sort select="(:the relative order is latest of self or other:)
               max((number(@index),
                    if(@other='') (:if no other, then use previous other:)
                      then preceding-sibling::*[@other!=''][1]/number(@other)
                      else number(@other)))"/>
    <xsl:if test="position()>1">,</xsl:if>
    <xsl:value-of select="."/>
  </xsl:for-each>

</xsl:template>

</xsl:stylesheet>
T:\ftemp>


-- Contact us for world-wide XML consulting and instructor-led training Free 5-hour video lecture: XSLT/XPath 1.0 & 2.0 http://ude.my/uoui9h Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Google+ profile: https://plus.google.com/116832879756988317389/about Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread