Re: [xsl] Using the Input Document to Control Generation of Numbers in the Output

Subject: Re: [xsl] Using the Input Document to Control Generation of Numbers in the Output
From: George Cristian Bina <george@xxxxxxxxxxxxx>
Date: Tue, 02 Oct 2007 17:41:50 +0300
Hi Richard,

Kerry, Richard wrote:
[...]
Since I wrote the above I've received George's solution for problem 3,
which I don't yet understand.


<one:one xmlns:one="http://www.example.com/one"; index="1"/>

Adds an element in a namespace different than the XSLT namespace, just to be selected by the variable below.

<xsl:variable name="one" select="document('')/*/one:one" xmlns:one="http://www.example.com/one"/>

The one variable points to the one:one element above, I need that below to get the default value 1 in case no previous index is found.

<xsl:template match="incoming">

We are on an incoming element.

  <xsl:choose>
   <xsl:when test="@index">

If that specifies an index then we just use it.

    <ougoing name="{@name}" index="{@index}"/>
   </xsl:when>
   <xsl:otherwise>

otherwise we count

<outgoing name="{@name}" index="{count(preceding-sibling::*) +

preceding siblings

(preceding-sibling::*[@index][1]/@index|$one/@index)[1] -
the index value of the first preceding sibling that has an index attribute or, if there is no preceding sibling with an index attribute we use the index from the one variable, that means the value 1


count(preceding-sibling::*[@index][1]/preceding-sibling::*)

and we remove the preceding elements after the first element that has an index as we added all the preceding elements in the first count above

}"/>



   </xsl:otherwise>
  </xsl:choose>

For a large number of elements you may end out of stack with a recursive approach unless the processor optimizes that.

In case you are not using XSLT 2.0 then you need to solve
(@size, 1)[1]
from Mike's code with something like the one:one approach from my example:

<one:one xmlns:one="http://www.example.com/one";>1</one:one>
<xsl:variable name="one" select="document('')/*/one:one" xmlns:one="http://www.example.com/one"/>



<xsl:template match="incoming">
<xsl:param name="total-so-far"/>
<xsl:variable name="new-total" select="$total-so-far + (@size | $one)[1]"/>;
<outgoing name="{@name}" index="{$new-total}"/>
<xsl:apply-templates select="following-sibling::incoming[1]">
<xsl:with-param name="total-so-far" select="$new-total"/>
</xsl:apply-templates>
</xsl:template>


Best Regards,
George
---------------------------------------------------------------------
George Cristian Bina - http://aboutxml.blogspot.com/
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

Current Thread