Stylesheet behavior varies depending on presence or absence of an xsl:message
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.
#2 Updated by Michael Kay about 1 year 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.
#3 Updated by Michael Kay about 1 year 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
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.
#4 Updated by Michael Kay about 1 year ago
Classic Java problem: TinyTree.java has a private property
root, but it inherits from
GenericTreeInfo which also has a private property
root, and the two are out of sync.
TinyTree.root and make
GenericTreeInfo.root protected, and the problem is solved.
Please register to edit this issue