Bug #1119
closedSecond predicate following // is erroneously evaluated
0%
Description
SourceForge user: elenz
The attached stylesheet should speak for itself. Run the stylesheet against itself to reproduce the problem.
Basically, when a second predicate follows "//", the second predicate is (apparently) being evaluated independently of the first. An implementation that computes the intersection of the two filtered results would normally be just fine, but not when independent evaluation results in a type error that otherwise wouldn't occur. (I'm only speculating here on the source of the bug.)
In the following expression, the my:name-att() function is apparently being called even for elements that don't have a "name" attribute. But the first predicate should prevent that from happening.
//*[@name][my:name-att(.)]
The type signature and return expression of my:name-att() is defined such that it won't be happy if you give it an element having no "name" attribute.
Given the above expression, I get this error (assuming that the source document has some elements that don't have a "name" attribute):
Error on line 9 of saxon_bug.xsl:
XTTE0780: An empty sequence is not allowed as the result of function my:name-att()
at my:name-att() (file:///c:/buildx/script2/schemaSync/saxon_bug.xsl#16)
The following workarounds work for me (separate the two predicates into different steps):
//*[@name]/self::node()[my:name-att(.)]
//*/@name/..[my:name-att(.)]
I don't know if "//" is essential, but when I simply put "/" instead of "//", it did not exploit the bug.
Files
Updated by Anonymous over 15 years ago
SourceForge user: mhkay
Evan, I'd be grateful if you followed protocol by raising problems first on the mailing list or forum. I prefer to keep the bugs tracker for confirmed bugs - if everyone raised every support issue here, there would be so much noise it would be very hard to search for genuine known bugs. Also, if a problem is raised here without being assigned to anybody then I don't actually get an alert.
Reordering of predicates is actually explicitly allowed by the infamous section 2.3.4 of the XPath spec: see http://www.w3.org/TR/xpath20/#id-errors-and-opt. However, in this case it's being done without any very good reason (merely as an unintended side-effect of rewriting the expression to use descendant::* rather than descendant-or-self::node()/child::*), so I'll change it so this doesn't happen. I don't like relying on the let-out of section 2.3.4 unless there's a real optimization benefit.
The correct way to write your code, according to the letter of the spec, is using if-then-else:
//*[if (@name) then my:name-att(.) else false()]
Michael Kay
Updated by Anonymous over 15 years ago
SourceForge user: elenz
Ack, there's the protocol right at the top. Any way to delete this?
Thanks for your insight into the nuances of the spec and for the recommended code fix.
Humbled and apologetic,
Evan
Please register to edit this issue