The Oliver Becker's XPath method
XPath 1.0 does not support conditional expressions, at least not with the syntactic sugar one can expect.
With XPath 1.0 it is easy to extract content and use it as part of a string, but what if the actual content must depend on some condition? For example: if some condition is true I want to generate the string 'FOO', otherwise I want to generate the string 'BAZZ'.
In this case we can use the Oliver Becker's XPath method.
This method is based on a property of the following snippet:
substring('FOO', number(not(condition_for_foo))*4), substring('BAZZ', number(not(condition_for_bazz))*5)
The numbers 4 and 5 are computed by adding 1 to the length of the string: they are equivalent to XPath's string-length('FOO')+1, and string-length('BAZZ')+1.
As a result of computing the conditions, all of the concat arguments will be empty strings except for one -- the one for which condition is true. As a consequence only one of the alternative strings will be concatenated into the generated result.
The reasoning goes like this:
- if the condition is true, then the boolean function number will convert not(condition) to 0 (the boolean function number always converts true values to 1 and false values to 0), hence passing 0 as the second argument of the substring function (under which case substring generates a copy of the source string)
- if the condition is false, then the boolean function number will convert not(condition) to 1, hence passing the string length + 1 as the second argument of the substring function (under which case substring generates an empty string)
This method can be used with multiple conditions, as long as exactly one of
them is true:
substring('FOO', number(not(@attr='f'))*4), substring('BAZZ', number(not(@attr='b'))*5), substring('FOOBAR', number(not(@attr='fb'))*7)
In the snippet above, if @attr='f', then only the first
substring will be non-empty and the resulting string will be 'FOO'.
I found this method useful when creating metadata to be associated to XML content stored in a database.