Bug #4632


Stylesheet behavior varies depending on presence or absence of an xsl:message

Added by Norman Tovey-Walsh almost 4 years ago. Updated over 3 years ago.

Start date:
Due date:
% Done:


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


Hi Mike,

I really hope this turns out to be reproducible. I've packaged up a test case that is (currently) reproducible for me, but I'm pretty sure it's come and gone a couple of times while I was chasing it. I'll email the zip to you.

Basically, if you run saxon address.001.xml -xsl:pass/docbook.xsl -o:/dev/null it succeeds and if you run the same document against fail/docbook.xsl, it fails. The failure is an attempt to resolve against a URI that isn't absolute (in fact, it's the empty string). Putting in an xsl:message that prints out the base URI causes it to not be empty.

I'm in the middle of a significant refactoring exercise, so I'm afraid the test case is large and the code is a bit of a mess. As I said, it was very slippery so I just stopped and packaged up the first reproducible case I could catch.

Actions #1

Updated by Michael Kay almost 4 years ago

I'll look into it. When xsl:message affects the outcome it's usually because the presence of the xsl:message disables an optimization, and the optimization is incorrect.

Actions #2

Updated by Michael Kay almost 4 years ago

I haven't got to the bottom of this -- it's pretty complex -- but because base-uri() is effectively implemented as a memo function, the call on base-uri() within the "extra" xsl:message iinstruction in the "pass" stylesheet is causing data to be held on the containing document node, which somehow has the consequence that the (different) document node referenced in the "offending" call on base-uri() has a non-null base-uri property, whereas in the "fail" case that property is empty.

Actions #3

Updated by Michael Kay almost 4 years ago

I've changed the "fail" case to output a message at the point where the "pass" case does: this message outputs "MBASE"+base-uri() in the pass case, and simply "MBASE" in the fail case.

Doing side-by-side debugging, at the point where we hit the xsl:message, the context node in both cases seems identical. In particular, the document node at the root of the tree has a correct non-null baseURI property.

We then step on to the first call on base-uri(), which is within the MBASE message for the pass case, but some time later in the fail case. We're calling base-uri() on the same node (the first element child of the document), but in the pass case the document node still has a correct non-null baseURI property, while in the fail case the baseURI property is now null.

If we look more carefully at the fail case, on entry to the base-uri() function, the element node has a parent node which is TinyDocumentImpl#4864, with a base URI of null, while the containing tree has a root node which is TinyDocumentImpl#4571, with a correct non-null baseURI property.

It's not intrinsically wrong that we have multiple Java objects representing the same XDM node, because these are "flyweight" objects created transiently on demand. But it's wrong that they should have different properties!

So the essence of the problem is that the two calls on base-uri() have used slightly different routes to get to the information and have found different properties. Since base-uri() is a memo function, the value found by the first call for any node is the one that matters.

Actions #4

Updated by Michael Kay almost 4 years ago

Classic Java problem: has a private property root, but it inherits from GenericTreeInfo which also has a private property root, and the two are out of sync.

Drop TinyTree.root and make GenericTreeInfo.root protected, and the problem is solved.

Actions #5

Updated by Michael Kay almost 4 years ago

  • Category set to Internals
  • Status changed from New to Resolved
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Applies to branch 9.9 added
  • Fix Committed on Branch 10, 9.9 added

Patch committed on the 9.9 and 10 branches.

Actions #6

Updated by Michael Kay almost 4 years ago

While we're about it, DominoTree also inherits from GenericTreeInfo and has the same problem.

Further fix committed (without testing).

Actions #7

Updated by O'Neil Delpratt almost 4 years ago

  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 10.2 added

Bug fix applied in the Saxon 10.2 maintenance release.

Actions #8

Updated by O'Neil Delpratt over 3 years ago

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

Bug fix applied on the Saxon maintenance release.

Please register to edit this issue

Also available in: Atom PDF