Dear All,
 
again using Saxon 8.6.1 (I stick to it due to my project) I found a behavior of Saxon of which is not clear if it is a bug or feature.
 
Consider following stylesheet:
 
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">       
 <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
 <xsl:variable name="vars">
  <a>a1</a>
  <a>a2</a>
  <a>a3</a>
 </xsl:variable>
 <xsl:template match="/">
  <!-- (1) -->
  <xsl:for-each select="$vars/a" xmlns:Ex="java:test.Extensions">
   <b id="{Ex:createId()}">
    <xsl:value-of select="."/>
   </b>
  </xsl:for-each>
  <!-- (2) -->
  <xsl:for-each select="$vars/a" xmlns:Ex="java:test.Extensions">
   <c id="{Ex:createId()}_{position()}">
    <xsl:value-of select="."/>
   </c>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
 
Here an extension function createId() with no arguments is used wihtin a loop. The function shall create values like 'ID_<nr>' similar to generate-id() but the function has a side-effect that increases an internal counter:
 
package test;
 
public class Extensions
{
 private static long counter;
 
 public static String createId()
 {
  return "ID_" + (++counter);
 }
 
If I run the stylesheet using itself as input the result is:
 
D:\work\misc\saxon8>java -cp .;h:\saxon8\saxon8.jar -Xmx512M net.sf.saxon.Transform test.xsl test.xsl
<?xml version="1.0" encoding="UTF-8"?>
<b xmlns:Ex="java:test.Extensions" id="ID_1">a1</b>
<b xmlns:Ex="java:test.Extensions" id="ID_1">a2</b>
<b xmlns:Ex="java:test.Extensions" id="ID_1">a3</b>
<c xmlns:Ex="java:test.Extensions" id="ID_2_1">a1</c>
<c xmlns:Ex="java:test.Extensions" id="ID_3_2">a2</c>
<c xmlns:Ex="java:test.Extensions" id="ID_4_3">a3</c>
 
In the first loop,  the extension function createId() is called only once (three times 'ID_1')!
In the second loop,  the extension function createId() is invoked for each loop.
 
Does Saxon do some optimization in case (1) and extracts the function call of Ex:createId() because it is considered to be constant?
In case (2) such kind of optimization is impeded by position().
 
If true, could one ever use random() in XSLT ?
Is there anything said in the XSLT / XPath specs about how extension functions are considered to behave?
 
Mit den besten Gruessen/Best regards,

Dr. Michael Hedenus

VDO Automotive AG
SV P EG 1
Siemensstrasse 12, 93055 Regensburg, Germany

Ein Unternehmen des Continental-Konzerns/A Company of the Continental Corporation

Telefon/Phone: +49 941 790-6362
Telefax: +49 941 79013-6362
E-Mail: Michael.Hedenus-EXT@continental-corporation.com
http://www.continental-corporation.com
__________________________________________

VDO Automotive AG, Siemensstr. 12, 93055 Regensburg
Postfach/Postbox 10 09 43, 93009 Regensburg
Vorsitzender des Aufsichtsrats/Chairman of the Supervisory Board: Johannes Suttmeyer
Vorstand/Managing Board: Dr. Alan Hippe, Helmut Matschi
Sitz der Gesellschaft/Registered office: Regensburg
Registergericht/Commercial registry: Regensburg, HRB 10510

__________________________________________

Proprietary and confidential. Distribution only by express authority of Continental AG or its subsidiaries.