0

In XQuery 3.1 this (test) query checks for the presence of certain nodes by checking the name():

declare variable $doc := 
  doc("/db/apps/deheresi/data/ms609_0013.xml"));

let $ele := $doc//tei:sic | $doc//tei:surplus

for $n in $ele

let $output := switch ($n/name())
            case ("sic")
                return ($n)
            case ("surplus")
                return ($n)
            default return ""
return $output

Returns the following XML correctly:

<surplus reason="surplus">die</surplus>
<surplus reason="repeated">et Raimundum de las de Recaut</surplus>

Now, when I want to run my actual query againt the same document, to test for a node to produce HTML, it does not find the same tei:surplus:

declare variable $doc := 
  doc("/db/apps/deheresi/data/ms609_0013.xml"));

let $ele := $doc//tei:sic | $doc//tei:surplus

for $n in $ele 

let $output := switch ($n)
            case ($n/self::tei:sic)
                return (<span class="inter">
                        <i>ms. </i>
                        {$n/tei:orig/text()}
                        </span>,
                        <span class="diplo">
                        <i>corr. </i>
                        {$n/tei:corr/text()}
                        </span>)
            case ($n/self::tei:surplus[@reason="surplus"])
                return (<span><i>supp.</i>{$n/text()}</span>)
            case ($n/self::tei:surplus[@reason="repeated"])
                return (<span><i>supp. (dup.)</i>{$n/text()}</span>)
            default return  ""
 return $output

Is there something wrong with the way I'm testing the node on case that it does not find tei:surplus in the very same document?

NB: when I do the same for a document that contains the first case (tei:sic), it outputs fine. Evidently the test in principle should work!

Thanks in advance.

jbrehr
  • 775
  • 6
  • 19
  • It turns out that XQuery `switch` atomizes the operand expression. In this case, the node is reduced to a name. Therefore one needs to test some sort of string in each `case`. For this reasons the second switch would fail to return a result as I am testing nodes with therefore unpredictable outcomes from atomization. – jbrehr Oct 23 '18 at 13:49
  • 1
    See https://www.w3.org/TR/xquery-31/#id-typeswitch on how to check nodes in XQuery 3.1. – Martin Honnen Oct 23 '18 at 14:29

1 Answers1

1

The switch construct compares atomic values. You could use it like this:

switch (node-name($n))
case QName("http://tei-namespace/", "sic") return <something/>

Note the use of node-name() rather than name() to avoid any dependency on namespace prefixes.

But it's probably better to use typeswitch:

typeswitch ($n)
case element(tei:sic) return <something/>
Michael Kay
  • 156,231
  • 11
  • 92
  • 164