This method is based on a property of the following snippet:

concat(

 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:
concat(

 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.