3
votes

In my Xquery 3.1 module I have imported my " global variables" through a module import, one of which ($globalvar:MSGS) contains an XML document that I generally have no problems accessing through reference to the variable. For example this

$globalvar:MSGS//vocab[@xml:id="warning"]

will return

     <vocab xml:id="warning">
        <span lang="en">Warning! Your changes (OBJECTID) could not be saved!</span>
        <span lang="fr">Attention, vos modifications (OBJECTID) n’ont pas pu être sauvegardées !</span>
     </vocab>

But the following is returning an error err:XPDY0002 variable '$msg' is not set pointing to line 7-8:

1. let $collid := $mydoc//collection-id/text()
2. let $errtitle :=   
3.         <msg-error-title>
4.              {
5.                let $msg := $globalvar:MSGS/id("warning")/span
6.                return 
7.                     <en>{replace($msg[@lang="en"]/text(),"OBJECTID",$collid)}</en>,                 
8.                     <fr>{replace($msg[@lang="fr"]/text(),"OBJECTID",$collid)}</fr>
9.               }
10.         </msg-error-title>
11. return $errtitle

But if I remove the inner let ... return and make direct reference to $globalvar:MSGS like below, there are no errors:

let $collid := $mydoc//collection-id/text()
let $errtitle :=   
         <msg-error-title>
                {
                 <en>{replace($globalvar:MSGS/id("warning")/span[@lang="en"]/text(),"OBJECTID",$collid)}</en>,                 
                 <fr>{replace($globalvar:MSGS/id("warning")/span[@lang="fr"]/text(),"OBJECTID",$collid)}</fr>
                 }
         </msg-error-title>
return $errtitle

I don't understand why $msg isn't set in the first example? Is there an alternative?


added test

let $collid := "FOOID"
let $xml := 
    <vocab xml:id="warning">
        <span lang="en">Warning! Your changes (OBJECTID) could not be saved!</span>
        <span lang="fr">Attention, vos modifications (OBJECTID) n’ont pas pu être sauvegardées !</span>
     </vocab>

let $errtitle :=   
    <msg-error-title>
            {let $msg := $xml/id("warning")/span
             return 
                <en>{replace($msg[@lang="en"]/text(),"OBJECTID",$collid)}</en>,
                <fr>{replace($msg[@lang="fr"]/text(),"OBJECTID",$collid)}</fr>
             }
    </msg-error-title>
return $errtitle
1
It looks suspiciously like a bug in your XQuery processor. What processor is this? Can you supply a complete repro? - Michael Kay
I've added a self-contained test at bottom of post. This is eXist 4.7. - jbrehr

1 Answers

5
votes

Your test case fails in Saxon with

Static error XPST0008 Unresolved reference to variable $msg

The problem is that "," doesn't bind as closely as you think, so you need extra parens around the return expression:

       return (
                <en>{replace($msg[@lang="en"]/text(),"OBJECTID",$collid)}</en>,
                <fr>{replace($msg[@lang="fr"]/text(),"OBJECTID",$collid)}</fr>
       )