Project

Profile

Help

Bug #3432

closed

Error running fn:transform() when TimingTraceListener is set

Added by Mark Dunn about 7 years ago. Updated about 7 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XPath conformance
Sprint/Milestone:
-
Start date:
2017-09-07
Due date:
% Done:

100%

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

Description

When running the attached stylesheet test-XPDY0002-error.xsl I get the following error:

Error in xsl:if/@test on line 18 column 31 of test-fn-transform.xsl:
XPDY0002: Finding root of tree: the context item is absent

But ONLY if TimingTraceListener is set.

The stylesheet uses a package, which in turn uses fn:transform to run a stylesheet test-fn-transform.xsl

test-fn-transform.xsl has a root-level variable set using an XPath from the document root.

Among the set of files attached are a batch file and an Ant build file.

Removing -TP:test-xslt-trace-profile.html from the batch file also removes the error

Removing

and from the Ant XSLT task also removes the error.

I'm using Saxon HE 9.8.0.4


Files

test-fn-transform.zip (3.98 KB) test-fn-transform.zip Mark Dunn, 2017-09-07 16:27
Actions #1

Updated by Michael Kay about 7 years ago

  • Status changed from New to In Progress

The fn:transform() code is not setting the global context item before invoking Controller.applyTemplates(). It should do so: simple bug, easy to fix.

This leaves the question, why does it work when tracing is not enabled?

Well, Controller.globalContextItem is being set to the initial source doc in Controller.transformDocument() at #2286. This seems incorrect. But how come it doesn't happen when tracing is enabled? Well, this is because, with tracing enabled, global variables are evaluated eagerly (so that the trace output is intelligible). In fact, they are initialized before Controller.transformDocument (incorrectly) sets the global context item.

The primary fix here is to ensure that fn:transform calls Controller.setGlobalContextItem() if the source-node option is present. This is straightforward (though it suggests the need for a couple of extra test cases).

The secondary problem, of preventing globalContextItem being set on the applyTemplates() path, is trickier, because the same code is used in a wide variety of situations and there is a serious risk of causing regression to other workloads. Nevertheless, it's clearly wrong, and it could cause worse problems than simply a failure to throw XPDY0002: it could cause the global context item to have the wrong value. So I shall try and correct this one too.

Actions #2

Updated by Michael Kay about 7 years ago

Noted in passing that the fn:transform() code does not seem to do anything useful with the value of the global-context-item option when this is supplied in place of source-node.

Actions #3

Updated by Michael Kay about 7 years ago

My first attempt to remove the setting of globalContextItem from Controller.transformDocument() results in two s9api unit tests failing: XsltTransformer.testContextNotRoot and XsltTransformer.testContextNotRootNamedTemplate. These tests are handling the obscure rule (defined in the XSLT 1.0 spec, but translated here to 3.0 terminology) that when the initial match selection is a non-root node, the global context item is the root node of the corresponding document.

(XSLT 2.0 ยง9.5: For a global variable or the default value of a stylesheet parameter, the expression or sequence constructor specifying the variable value is evaluated with a singleton focus based on the root node of the tree containing the initial context node. )

After some delicate rearrangement of code I have now got all the JAXP and s9api unit tests to pass, but there's still a slight risk some user workloads could be affected because this rule wasn't being applied on all paths.

Actions #4

Updated by Michael Kay about 7 years ago

  • Tracker changed from Support to Bug
  • Category set to XPath conformance
  • Status changed from In Progress to Resolved
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Fix Committed on Branch 9.8 added

Fix committed:

  1. fn:transform now correctly sets the global context item taking into account the two options source-node and global-context-item

  2. Controller.transformDocument() no longer sets the global context item to the supplied source node; instead, callers of this function that require this behaviour do it themselves.

Actions #5

Updated by O'Neil Delpratt about 7 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 9.8.0.5 added

Bug fix applied in the Saxon 9.8.0.5 maintenance release.

Please register to edit this issue

Also available in: Atom PDF