Re: Spurious error on recursive invocation of fn:transform

Michael Kay <mike-JkSD5nQpfvpWk0Htik3J/[email protected]> Wed, 25 Nov 2020 09:22:56 +0000
Newsgroups gmane.text.xml.saxon.help
Message-ID <[email protected]>
I've moved the issue here:

https://saxonica.plan.io/issues/4837

and I'd be grateful if further discussion takes place on that tracker.

The heart of the issue is that we've got two documents with the same URI: the stylesheet for fn:transform() has the same systemId as the source document. That can happen very easily because variious XSLT instructions create new documents that have the same base URI as the stylesheet; and if it does happen, things are going to break, because the rules for doc() assume that URIs are unique identifiers for documents. So it's not going to be an easy one to solve.

It's quite possible that there have been changes in 10.3. We fixed bug https://saxonica.plan.io/issues/4795 which was another issue concerned with the fact that there isn't a one-to-one correspondence between URIs and documents - in that case it was caused by HTTP redirects, but the underlying architectural problem is the same. It's a bit of a swamp, and when your foundations aren't solid, fixing one bug tends to cause others.

Michael Kay
Saxonica

> On 25 Nov 2020, at 01:41, Ihe Onwuka <[email protected]> wrote:
> 
> xsl:copy doesn't feature in the original problem which instead uses xsl:sequence
> 
> On Tue, Nov 24, 2020 at 7:08 PM Michael Kay <mike-JkSD5nQpfvpWk0Htik3J/[email protected] <mailto:mike-JkSD5nQpfvpWk0Htik3J/[email protected]>> wrote:
> Thanks, I've reproduced the problem. As expected, it's all to do with base URIs.
> 
> I haven't got to the bottom of it yet, but I think the heart of the issue is that <xsl:copy> is creating a document whose base URI is defined to be the same as the stylesheet URI, and then we are using this URI as a key into the document cache for a call on doc(). Which ignores the fact that multiple documents can have the same base URI: the base URI is not a unique identifier for a document. Unfortunately the JAXP interfaces like the Source object and the URIResolver use a single property (systemId) to represent both base URIs and unique document URIs, so it's easy to get them mixed up.
> 
> Michael Kay
> Saxonica
> 
>> On 24 Nov 2020, at 14:57, Ihe Onwuka <[email protected] <mailto:[email protected]>> wrote:
>> 
>> 
>> On Tue, Nov 24, 2020 at 7:32 AM Michael Kay <mike-JkSD5nQpfvpWk0Htik3J/[email protected] <mailto:mike-JkSD5nQpfvpWk0Htik3J/[email protected]>> wrote:
>>> 
>>> The usage of doc('') is not the causation here 
>>> 
>>> stylesheet-node : doc('fullpathToTheStylesheetAsGeneratedWithdocument-uri/myStylesheet.xsl')
>>> 
>>> the exact same result.
>>>  
>> 
>> It's not so much the use of doc(""), as the reliance on preservation of a base URI.
>> 
>> Having said that, if you can put together a repro we'll be happy to look at it. I think it's fairly clear the problem is happening because the base URI is being lost through the call on fn:transform(), but whether losing it is a bug or an application error is something we can only determine if we study the detail.
>> 
>> Michael Kay
>> Saxonica
>> 
>> Here. 
>> 
>> Here is bug.xsl
>> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform <http://www.w3.org/1999/XSL/Transform>"
>>                 xmlns:fn="http://www.w3.org/2005/xpath-functions <http://www.w3.org/2005/xpath-functions>"
>>        xmlns:xs="http://www.w3.org/2001/XMLSchema <http://www.w3.org/2001/XMLSchema>"
>>        xmlns:local="urn:local"
>> version="3.0" >
>>   
>>    <xsl:mode on-no-match="shallow-copy"/>
>>    <xsl:function name="local:generateNextVersion" as="document-node()">
>>       <xsl:param name="currentVersion" as="document-node()"/>
>>       <xsl:variable name="isFinalVersion" as="xs:boolean" select="$currentVersion/* eq '3'"/>
>>       <xsl:sequence select="if ($isFinalVersion)
>>                             then $currentVersion
>>                             else local:generateNextVersion(fn:transform(map { 
>>                                                                      'stylesheet-node' : doc(''),
>>                                                     'source-node'     :  $currentVersion
>>                                                             })?output)"/> 
>>    </xsl:function>
>> 
>>    <xsl:template match="*"> 
>>   <xsl:message select="."/>
>>       <xsl:copy>	  
>>          <xsl:sequence select="let $customizedResult := fn:transform(map {
>>                                                               'stylesheet-node' :  doc('bugs2.xsl'),
>>                                                               'source-node'     :  /
>>                                                                })?output 
>>                                return  local:generateNextVersion($customizedResult)"/> 
>>        </xsl:copy>
>>    </xsl:template>
>> 
>>  </xsl:stylesheet>
>> 
>> Here is bugs2.xsl
>> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform <http://www.w3.org/1999/XSL/Transform>"
>>                 xmlns:fn="http://www.w3.org/2005/xpath-functions <http://www.w3.org/2005/xpath-functions>"
>> version="3.0" >
>>   
>>    <xsl:mode on-no-match="shallow-copy"/>
>>    <xsl:template match="*">
>>       <xsl:copy>
>>          <xsl:value-of select=". + 1"/>	     
>>       </xsl:copy>
>>    </xsl:template>
>> 
>>  </xsl:stylesheet>
>> 
>> Here is input XML
>> 
>> <bug>1</bug>
>> 
>> Reproduction instructions. 
>> 
>> Run the transform bug.xsl against input bug.xml and see the xsl:message output below
>> 
>> <bug>1</bug>
>> <bug>2</bug>
>> 
>> Change bug.xsl to test for $currentVersion eq '4' instead of 3
>> 
>> crashes as below
>> 
>> <bug>1</bug>
>> <bug>2</bug>
>> Error in bugs2.xsl:
>>   XTSE0150  The supplied file does not appear to be a stylesheet
>> Static error in bugs2.xsl:
>>   XTSE0150  The supplied file does not appear to be a stylesheet
>> Error in bugs2.xsl:
>>   XTSE0150  The supplied file does not appear to be a stylesheet
>> at function local:generateNextVersion in bug.xsl:
>>      invoked by function call
>>   In template rule with match="*" of bug.xsl
>>      invoked by built-in template rule (shallow-copy)
>> The supplied file does not appear to be a stylesheet
>> 
>> 
>> 
>> 
>>  
> 
> _______________________________________________
> saxon-help mailing list archived at http://saxon.markmail.org/
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/saxon-help

_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
[email protected]
https://lists.sourceforge.net/lists/listinfo/saxon-help