Project

Profile

Help

Bug #4667

transform() requires cache to be disabled in some cases?

Added by Air Quick about 2 months ago. Updated 5 days ago.

Status:
New
Priority:
Low
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2020-08-03
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:

Description

https://www.w3.org/TR/xpath-functions-31/#func-transform

cache ... This option has no effect on the result of the transformation but may affect efficiency.

The spec says, "no effect on the result".

However, on Saxon, the cache option in transform() does have some effect on the result.

Is it the user's responsibility to disable cache in some cases on Saxon? If so, when?

Here is a complete repro (a file called test.xsl):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="#all" version="3.0"
  xml:base="https://raw.githubusercontent.com/xspec/xspec/9fa77d2dc6fc94e50bbff38112e3252769c663a1/test/xslt-package/filter/"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output indent="yes" omit-xml-declaration="yes" />

  <xsl:template name="xsl:initial-template">
    <xsl:call-template name="scenario">
      <xsl:with-param name="location" select="'UK'" />
    </xsl:call-template>

    <xsl:call-template name="scenario">
      <xsl:with-param name="location" select="'FR'" />
    </xsl:call-template>

    <xsl:call-template name="scenario">
      <xsl:with-param name="location" select="'FR'" />
      <xsl:with-param name="cache" select="false()" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="scenario">
    <xsl:param as="xs:string" name="location" />
    <xsl:param as="xs:boolean" name="cache" select="true()" />

    <!--
      ******************************************************************
      All the external files are available via /xsl:stylesheet/@xml:base
      ******************************************************************
    -->
    <xsl:variable as="map(xs:string, item()*)" name="transform-options">
      <xsl:map>
        <xsl:map-entry key="'cache'" select="$cache" />
        <xsl:map-entry key="'delivery-format'" select="'raw'" />
        <xsl:map-entry key="'source-node'" select="doc('data.xml')" />
        <xsl:map-entry key="'stylesheet-location'" select="resolve-uri('use.xsl')" />
        <xsl:map-entry key="'vendor-options'">
          <xsl:map>
            <xsl:map-entry key="QName('http://saxon.sf.net/', 'configuration')">
              <configuration xmlns="http://saxon.sf.net/ns/configuration">
                <xsltPackages>
                  <package name="http://example.org/filter.xsl"
                    sourceLocation="{resolve-uri('package/filter.xsl')}" version="1.0">
                    <withParam name="filter" select="'location = ''{$location}'''" />
                  </package>
                </xsltPackages>
              </configuration>
            </xsl:map-entry>
          </xsl:map>
        </xsl:map-entry>
      </xsl:map>
    </xsl:variable>

    <scenario>
      <xsl:value-of select="transform($transform-options)?output//location" />
    </scenario>
  </xsl:template>
</xsl:stylesheet>
$ java -jar saxon-he-10.1.jar -it -xsl:test.xsl
<scenario>UK</scenario>
<scenario>UK</scenario>
<scenario>FR</scenario>

If "no effect on the result" were true, the 2nd and the 3rd in the output would be the same. That is:

<scenario>UK</scenario>
<scenario>FR</scenario>
<scenario>FR</scenario>

History

#1 Updated by Michael Kay about 2 months ago

  • Tracker changed from Support to Bug

Thanks, yes, I know you've raised this before and we failed to respond. I'm reclassifying it as a bug. I'm not sure if we'll change the documentation or the code but we need to sort it out.

There are two statements in the spec: cache "no effect on the result of the transformation", and vendor-options: "The meaning of the associated value is ·implementation-defined·". I think that means that so long as we document the effect of a vendor option, it's OK for it to override the effect of other spec-defined options.

#2 Updated by Michael Kay about 2 months ago

First. let's see exactly how this is going to work currently. I think it's like this:

If you specify vendor-options?configuration in the fn:transform() optiions, then Saxon will build the defined Configuration.

Then, if `cache="yes" is specified, it will look in the cache to see if a cached stylesheet exists, and if it does, it will use it, running it in the Configuration that it was compiled under (and thus ignoring the Configuration that has just been created). If it doesn't exist, the stylesheet will be compiled in the new Configuration and saved in the cache.

What are the alternatives?

(a) We could reject/ignore the request for caching if a configuration is specified. That would be unfortunate since it would mean you can't use a "compile on first use" stylesheet that needs access to library packages.

(b) We could try and check that the new configuration is compatible with the old when deciding whether to use a stylesheet that exists in the cache: for example that it uses the same library packages, etc etc. Perhaps that's the ideal, but it's a rather complicated test to perform given the large number of parameters that might be present in the configuration.

(c) We could try and check that the new configuration is identical with the old: any change and retrieval from cache is disabled. That's perhaps a more feasible approach, since we could use some kind of checksum for the identify check.

(d) We could provide explicit options in the vendor options. Gets a bit complicated...

Perhaps (c) is a reasonable way forward. But it's beyond the scope of a bug fix. I think the short term fix should probably be to document what the software currently does.

#3 Updated by Michael Kay about 1 month ago

I'm inclined to say that we should do the following:

(a) check much earlier (in particular, before loading a Configuration or configuring an XSLTCompiler) whether the compiled stylesheet already exists in cache.

(b) document for vendor-options/configuration that the configuration is ignored if the stylesheet is found in cache. This conflicts with the statement that cache="yes" has no effect on the transformation results; but the whole idea of vendor-options is to allow the standard behaviour to be customised, so we can define our own rules on this.

#4 Updated by Michael Kay 5 days ago

Discussed at team meeting. We felt that comment #3 was probably the right way to go.

Please register to edit this issue

Also available in: Atom PDF