Hi Everyone,
I have an xml document with elements such as <div n=“21”>. If I run the query doc(“file.xml")//div[@subtype="chapter"]//*/parent::div[@n=21], I get the relevant div element, even if 21 is passed as an integer. On the other hand, if I type doc(“file.xmll")//div[@n=21], I get the error "Cannot convert to xs:double”, which can be solved by writing doc(“myfile.xmll")//div[@n=“21”].
Is this due to the fact that BaseX tries to convert the values of @n of all div elements into a number and, if it happens that the @n values returned are all numbers, then an error is not raised (the comparison is then possible), otherwise it is? Is this BaseX specific? Thanks.
Best, Giuseppe
Hi Giuseppe,
Is this due to the fact that BaseX tries to convert the values of @n of all
div elements into a number and, if it happens that the @n values returned are all numbers, then an error is not raised (the comparison is then possible), otherwise it is? Is this BaseX specific? Thanks.
Exactly; that’s standard XQuery. You can use an additional predicate to restrict the comparisons to valid integers:
<xml> <div n='a'/> <div n='21'/> <!-- result --> <div n=' 21 '/> <!-- result --> </xml>//div[@n[. castable as xs:integer][. = 21]]
Using string comparisons is usually the easier way, and it’s better supported by our index structures. However, if your numeric data is irregular and has additional whitespaces (such as in the third <div> element in my example), string comparisons may be too strict.
A side note: I was surprised to see that Saxon EE 10 raises an exception for my example query. It seems that the predicates are swapped, and the comparison is evaluated before the cast check. Maybe the behavior has been adapted in a more recent version. – A workaround is to use the and expression:
<x>a</x>[. castable as xs:integer and . = 21]
In BaseX, a predicate with an and expression will automatically be rewritten to multiple predicates, as simple predicates can be further optimized more easily, and predicates will always be evaluated in the order they are written down.
Ciao, Christian
On Tue, 2022-04-26 at 19:54 +0200, Christian Grün wrote:
A side note: I was surprised to see that Saxon EE 10 raises an exception for my example query. It seems that the predicates are swapped, and the comparison is evaluated before the cast check. Maybe the behavior has been adapted in a more recent version. – A workaround is to use the and expression:
<x>a</x>[. castable as xs:integer and . = 21]
This is also not guaranteed. You can, however, write,
[if (. castable as xs:integer) then (. = 21) else false() ]
This one is guaranteed not to raise dynamic errors in the unused expression.
Liam
Thank you, Christian, as always very useful!
On 26. Apr 2022, at 19:54, Christian Grün christian.gruen@gmail.com wrote:
Hi Giuseppe,
Is this due to the fact that BaseX tries to convert the values of @n of all div elements into a number and, if it happens that the @n values returned are all numbers, then an error is not raised (the comparison is then possible), otherwise it is? Is this BaseX specific? Thanks.
Exactly; that’s standard XQuery. You can use an additional predicate to restrict the comparisons to valid integers:
<xml> <div n='a'/> <div n='21'/> <!-- result --> <div n=' 21 '/> <!-- result --> </xml>//div[@n[. castable as xs:integer][. = 21]]
Using string comparisons is usually the easier way, and it’s better supported by our index structures. However, if your numeric data is irregular and has additional whitespaces (such as in the third <div> element in my example), string comparisons may be too strict.
A side note: I was surprised to see that Saxon EE 10 raises an exception for my example query. It seems that the predicates are swapped, and the comparison is evaluated before the cast check. Maybe the behavior has been adapted in a more recent version. – A workaround is to use the and expression:
<x>a</x>[. castable as xs:integer and . = 21]
In BaseX, a predicate with an and expression will automatically be rewritten to multiple predicates, as simple predicates can be further optimized more easily, and predicates will always be evaluated in the order they are written down.
Ciao, Christian
basex-talk@mailman.uni-konstanz.de