Project

Profile

Help

Bug #3333

Using an XSLT 3.0 package indirectly by several routes

Added by Mark Dunn about 2 years ago. Updated almost 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XSLT 3.0 packages
Sprint/Milestone:
-
Start date:
2017-07-04
Due date:
% Done:

100%

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

Description

I'd like to be able to create a single package of common functions, variables, etc.

Something like this:

<xsl:package 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    name="http://www.oup.com/oup-academic-common-package"
    package-version="0.1"
    version="3.0">

    <xsl:use-package name="http://www.oup.com/logger" package-version="0.1"/>
    <xsl:use-package name="http://www.oup.com/generalVariables" package-version="0.1"/>
    <xsl:use-package name="http://www.oup.com/getDTD" package-version="0.1"/>

</xsl:package>

Both "logger" and "getDTD" packages need to use the "generalVariables" package.

The "generalVariables" package also needs to be available to the stylesheet that uses the "oup-academic-common-package".

My first attempt threw up duplicate variable error messages.

Then I had a go with xsl:accept. So now both the "logger" and "getDTD" packages contain this statement:

  <xsl:use-package name="http://www.oup.com/generalVariables" package-version="0.1">
    <xsl:accept component="*" names="*" visibility="private"/>
  </xsl:use-package>

Now my error message is:

java.lang.AssertionError: Saxon can't find the new component corresponding to variable oupdtg:filePathSeparator

oupdtg:fileSeparator is a variable defined in the "generalVariables" package:

<xsl:package 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    xmlns:oupdtg="http://www.oup.com/oupdtg" 
    name="http://www.oup.com/generalVariables"
    package-version="0.1"
    exclude-result-prefixes="#all"
    version="3.0">

    <xsl:variable name="oupdtg:newLine" as="xs:string" visibility="public">
        <xsl:text>&#x000d;&#x000a;</xsl:text>
    </xsl:variable>

    <xsl:variable name="oupdtg:quot" as="xs:string" visibility="public" select="'&quot;'"/>

    <xsl:variable name="oupdtg:filePathSeparator" as="xs:string" visibility="public" select="'[\\/]'"/>

</xsl:package>

If I use the three packages directly within my stylesheet (rather than wrapping them in the "oup-academic-common-package", the stylesheet works fine.

But is it possible to create this wrapper package?

test-packages.zip (6.65 KB) Stylesheets and packages for testing use-package hierarchy and visibility Mark Dunn, 2017-07-05 09:59 test-packages.zip

Related issues

Duplicated by Saxon - Bug #3367: function not found inside xslt package Duplicate 2017-07-31 Actions

History

#1 Updated by Michael Kay about 2 years ago

I think I need to see the source code (or a repro that demonstrates the problem) to understand what's going on here.

If something is public in generalVariables then it should become private within the packages that use it, so this conflict shouldn't happen -- in theory.

The code in this area hasn't had a large amount of exposure except to synthetic small-scale test cases so my instinct is to suspect a bug somewhere: in which case I will need a repro to investigate.

#2 Updated by Mark Dunn about 2 years ago

I've attached a set of files with two top-level stylesheets, which illustrate a couple of scenarios.

test-xslt3-packages-1.xsl

Uses "oup-academic-common-package", which uses "logger", "generalFunctions", "generalVariables", and "runner".

"logger" uses "generalVariables"

"generalFunctions" uses "generalVariables"

Error message:

javax.xml.transform.TransformerConfigurationException: net.sf.saxon.s9api.SaxonApiException: Duplicate variable oupdtg:city

test-xslt3-packages-2.xsl

Uses "runner", which uses "logger" and "generalFunctions".

Error message:

java.lang.AssertionError: Saxon can't find the new component corresponding to variable oupdtg:city

Also included is an Ant build file and a batch file which I used to run the transformations using Saxon 9.8 HE. The error messages were the same using both methods of running the transformations.

#3 Updated by Michael Kay about 2 years ago

Sorry for the delay in responding. I've added some internal tracing to the code to show what's going on (it would seem a good idea to productize this). For the first case (packages-1) we have

Adding components from http://www.oup.com/generalVariables to http://www.oup.com/logger

variable oupdtg:city (PUBLIC) becomes PRIVATE

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/generalVariables to http://www.oup.com/generalFunctions

variable oupdtg:city (PUBLIC) becomes PRIVATE

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/logger to http://www.oup.com/runner

template oupdtg:log (PUBLIC) becomes PRIVATE

variable oupdtg:city (PRIVATE) becomes HIDDEN [1]

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/generalFunctions to http://www.oup.com/runner

variable oupdtg:city (PRIVATE) becomes HIDDEN

function oupdtg:getCity#0 (PUBLIC) becomes PRIVATE

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/logger to http://www.oup.com/oup-academic-common-package

template oupdtg:log (PUBLIC) becomes PRIVATE

variable oupdtg:city (PRIVATE) becomes HIDDEN

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/generalFunctions to http://www.oup.com/oup-academic-common-package

variable oupdtg:city (PRIVATE) becomes HIDDEN

function oupdtg:getCity#0 (PUBLIC) becomes PRIVATE

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/generalVariables to http://www.oup.com/oup-academic-common-package

variable oupdtg:city (PUBLIC) becomes PRIVATE

mode xsl:unnamed (PRIVATE) becomes HIDDEN

Adding components from http://www.oup.com/runner to http://www.oup.com/oup-academic-common-package

template oupdtg:log (PRIVATE) becomes HIDDEN

variable oupdtg:city (PUBLIC) becomes PRIVATE [2]

Error at procedure oupdtg:city on line 19 of generalVariables.xsl:

XTSE3050: Duplicate variable oupdtg:city

Duplicate variable oupdtg:city

Messages labelled [1] and [2] appear to show a contradiction - the variable should be HIDDEN in runner, and therefore remain HIDDEN in academic-common.

#4 Updated by Michael Kay about 2 years ago

What's happening here is specific to global variables (as distinct from other kinds of component). After collecting together all the components acquired from a used package, we allocate slot numbers for space allocation in the Bindery for the package (StylesheetPackage.allocateBinderySlots()). This invokes the method registerGlobalVariable(), which has the side-effect of creating a PUBLIC global variable with the requisite name. This is clearly incorrect.

I'm concerned about another couple of things noticed while analyzing this:

(a) where a package acquires two hidden components with the same name from different packages, they are being merged into one. This seems wrong. The merging happens because StylesheetPackage.hiddenComponents is a map keyed on symbolic name.

(b) the process of acquiring components from a used package seems to ignore hidden components in the used package.

#5 Updated by Michael Kay about 2 years ago

  • Tracker changed from Support to Bug
  • Category set to XSLT 3.0 packages
  • Status changed from New to In Progress
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Applies to branch 9.8 added

#6 Updated by Michael Kay about 2 years ago

  • Subject changed from Can I create a package containing a hierarchy of used packages? to Using an XSLT 3.0 package indirectly by several routes

#7 Updated by Michael Kay about 2 years ago

I've fixed the problems identified above, and compilation of packages-1.xsl now fails with

Static error in {oupdtg:getCity()} in expression in xsl:copy-of/@select on line 16 column 53 of test-xslt3-packages-1.xsl:
  XPST0017: Cannot find a matching 0-argument function named {http://www.oup.com/oupdtg}getCity()
Static error at xsl:call-template on line 15 column 51 of test-xslt3-packages-1.xsl:
  XTSE0650: No template exists named oupdtg:log

which is correct, because these components are private in common-package and therefore hidden in packages-1.

Adding

<xsl:expose component="*" names="*" visibility="public"/>

to common-package doesn't help because the components are private in common-package and therefore cannot be exposed as public. Instead I need to insert an xsl:accept element into each xsl:use-package, in the form

<xsl:accept component="*" names="*" visibility="public"/>

after which I get the (presumably) correct result

<output><log>Oxford</log><city>Oxford</city></output>

#8 Updated by Michael Kay about 2 years ago

Confirmed that the above changes cause no regression in test-sets package, use-package, expose, accept, or override.

#9 Updated by Michael Kay about 2 years ago

The second test, test-packages-2, also runs successfully after making these changes.

#10 Updated by Mark Dunn about 2 years ago

That's the correct output, and adding the xsl:accept/ statement to common-package to produce it makes sense to me.

Glad to be of help flushing out this issue!

#11 Updated by Michael Kay about 2 years ago

  • Status changed from In Progress to Resolved

#12 Updated by O'Neil Delpratt almost 2 years ago

  • Duplicated by Bug #3367: function not found inside xslt package added

#13 Updated by O'Neil Delpratt almost 2 years ago

  • % Done changed from 0 to 100
  • Fix Committed on Branch 9.8 added

#14 Updated by O'Neil Delpratt almost 2 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 9.8.0.4 added

Bug fix applied in the Saxon 9.8.0.4 maintenance release.

Please register to edit this issue

Also available in: Atom PDF