13

I have an external variable coming in as a string and I would like to do a switch/case on it. How do I do that in xquery?

Sixty4Bit
  • 12,852
  • 13
  • 48
  • 62

5 Answers5

25

Starting with XQuery 1.1, use switch:

http://www.w3.org/TR/xquery-11/#id-switch

switch ($animal) 
   case "Cow" return "Moo"
   case "Cat" return "Meow"
   case "Duck" return "Quack"
   default return "What's that odd noise?" 
jh314
  • 27,144
  • 16
  • 62
  • 82
jonathan robie
  • 266
  • 3
  • 2
4

Just use a series of if expressions:

if ($room eq "bathroom") then "loo"
else if ($room eq "kitchen")  then "scullery"
else "just a room"

Using a typeswitch is hiding what you are really doing.

Which of these methods is most efficient will depend on the XQuery processor you are using. In an ideal world it should only be a matter of taste, as it should be down to the optimizer to select the appropriate method, but if performance is important it is worth benchmarking both versions. I would be very surprised if a processor optimized the node construction out of your example, and didn't optimize my example to a specialized switch.

jh314
  • 27,144
  • 16
  • 62
  • 82
Oliver Hallam
  • 4,242
  • 1
  • 24
  • 30
  • Sometimes it is nice and elegant to hide what you really do if you dont forget that you are doing it ... – Ar3s Feb 11 '10 at 21:16
  • I down voted this because the question is trying to find the syntax of switch/case not if/else. – Sixty4Bit Oct 12 '10 at 21:54
  • 1
    @Sixty4Bit - When I answered the question the behaviour of switch was not finalized, which was why I posted my second answer in February! – Oliver Hallam Oct 13 '10 at 15:43
3

If your processor supports XQuery 1.1, then you can simply do:

switch ($room) 
  case "bathroom" return "loo"
  case "kitchen" return "scullery"
  default return "just a room"
jh314
  • 27,144
  • 16
  • 62
  • 82
Oliver Hallam
  • 4,242
  • 1
  • 24
  • 30
3

XQuery doesn't have a function for switching on anything other than elements.

The first thing you do is convert your string to an element.

let $str := "kitchen"
let $room := element {$str} {}

Then just use typeswitch to do a normal switch:

return typeswitch($room)
  case element(bathroom) return "loo"
  case element(kitchen) return "scullery"
  default return "just a room"

Please note, this may be a MarkLogic only solution.

jh314
  • 27,144
  • 16
  • 62
  • 82
Sixty4Bit
  • 12,852
  • 13
  • 48
  • 62
1

For Saxon, you can use something like this:

declare function a:fn($i) {
typeswitch ($i)
 case element(a:elemen1, xs:untyped) return 'a' 
 case element(a:elemen2, xs:untyped) return 'b' 
 default return "error;"
};

https://rrusin.blogspot.com/2010/01/xquery4j-in-action.html

Cœur
  • 37,241
  • 25
  • 195
  • 267
Rafal Rusin
  • 623
  • 6
  • 12