This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 13494 - [XSLT 2.0] Node uniqueness returned from XSLT function.
Summary: [XSLT 2.0] Node uniqueness returned from XSLT function.
Status: NEW
Alias: None
Product: XPath / XQuery / XSLT
Classification: Unclassified
Component: XSLT 2.0 (show other bugs)
Version: 2nd Edition Recommendation
Hardware: PC Windows XP
: P2 normal
Target Milestone: ---
Assignee: Michael Kay
QA Contact: Mailing list for public feedback on specs from XSL and XML Query WGs
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-08-01 08:45 UTC by Vladimir Nesterovsky
Modified: 2012-05-16 22:11 UTC (History)
0 users

See Also:


Attachments

Description Vladimir Nesterovsky 2011-08-01 08:45:28 UTC
Running my XSLT with the Saxon engine, I've found some ambiguity as for implementation details of node uniquess returned from a function. That's an example:

<?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"
  xmlns:t="http://www.nesterovsky-bros.com/xslt/public"
  exclude-result-prefixes="t xs">

  <xsl:template match="/" name="main">
    <xsl:variable name="result">
      <root>
        <xsl:for-each select="1 to 3">
          <section-ref name-ref="{t:generate-id()}.s"/>

          <!--
          <xsl:variable name="id" as="xs:string" select="t:generate-id()"/>
          <section-ref name-ref="{$id}.s"/>
          -->
        </xsl:for-each>
      </root>
    </xsl:variable>

    <xsl:message select="$result"/>
  </xsl:template>

  <!-- This is siplified version. -->
  <!--
  <xsl:function name="t:generate-id" as="xs:string">
    <xsl:variable name="element" as="element()">
      <element/>
    </xsl:variable>

    <xsl:sequence select="generate-id($element)"/>
  </xsl:function>
  -->

  <!-- This is more complex version. See spec section 9.2 -->
  <xsl:function name="t:generate-id" as="xs:string">
    <xsl:call-template name="t:generate-id"/> 
  </xsl:function>

  <xsl:template name="t:generate-id" as="xs:string">
    <xsl:param name="name" as="xs:string" select="'a'"/>
    <xsl:param name="element" as="element()">
      <xsl:element name="{$name}"/>
    </xsl:param>

    <xsl:sequence select="generate-id($element)"/>
  </xsl:template>
</xsl:stylesheet>

I thought that the stylesheet should output elements with different values of name-ref attribute.

Unfortunately, Saxon behaves differently depending on how I write the code:

a) following produces same values:

   <section-ref name-ref="{t:generate-id()}.s"/>

b) this produces different values:

   <xsl:variable name="id" as="xs:string" select="t:generate-id()"/>
   <section-ref name-ref="{$id}.s"/>

In the course of discussion with Michael Kay he pointed that the behaviour is not strictly defined in the spec, so that's not an implementation bug.

I would like WG to clarify this behaviour.

Originally problem described at:
http://sourceforge.net/projects/saxon/forums/forum/94027/topic/4621860

Thanks.
Comment 1 Michael Kay 2011-08-09 22:53:45 UTC
This question is a difficult one.

The fact that two calls on a function can (or must?) deliver two nodes with distinct identity is a feature that very few applications are likely to depend on, and yet it greatly complicates the language semantics, and places considerable constraints on an optimizer. In fact the rules have never been very clearly stated in XSLT; there has been more of an attempt in XQuery.

The existence of the generate-id() function, whose result explicitly depends on node identity, exacerbates the problem.

(Saxon does attempt to ensure that repeated calls on a function that creates new nodes create different nodes each time, and cannot therefore (for example) be moved out of a loop. It also makes some attempts to recognize dependencies on generate-id(). But in the end, recognizing such dependencies N levels deep becomes increasingly difficult, and arguably impossible when dynamic invocation is taken into account.)

I think there is a good case for going the other way, and making it explicitly implementation-dependent whether two calls on a function with the same arguments construct the same node or different nodes. I find it hard to believe that many applications would be affected by this.

The application in this case is deliberately trying to take advantage of the node-identity peculiarity in order to produce a function that delivers different results each time it is called. Perhaps we should really be looking at this as an application requirement and considering how it should be addressed, rather than trying to define more predictable semantics for functions that depend on node identity? Perhaps we should look at how other functional languages tackle this problem.

(Personal response)
Comment 2 Michael Kay 2011-08-10 10:22:44 UTC
I have raised the related bug #13747 discussing this issue in the context of XQuery 3.0 and XSLT 3.0, where new issues arise such as higher-order functions.
Comment 3 Vladimir Nesterovsky 2011-09-14 06:45:12 UTC
(In reply to comment #2)
> I have raised the related bug #13747 discussing this issue in the context of
> XQuery 3.0 and XSLT 3.0, where new issues arise such as higher-order functions.

Whether the resolution of the bug #13747 applies to this bug also?