xqueryexist-db

Is it possible to pass a uri parameter with xi:include in exist-db?


I have an exist-db .xql page where I am wrapping three other .xql pages via xi:include:

(:==========
Declare namespaces
==========:)
declare namespace mwjl = "http://minorworksoflydgate.net/mwjl";
declare namespace m = "http://minorworksofjohnlydgate.net/model";
declare namespace tei = "http://www.tei-c.org/ns/1.0";
declare namespace xi = "http://www.w3.org/2001/XInclude";

(:==========
Declare global variables to path
==========:)
declare variable $exist:root as xs:string := 
    request:get-parameter("exist:root", "xmldb:exist:///db/apps");
declare variable $exist:controller as xs:string := 
    request:get-parameter("exist:controller", "/mwjl-app");
declare variable $path-to-data as xs:string := 
    $exist:root || $exist:controller || '/data';
declare variable $docPath as xs:string := "paratext/Lydgate_Main.xml";

(:===
Declare variable
===:)
declare variable $work := doc("/db/apps/mwjl-app/data/" || $docPath);
declare variable $TEI as element(tei:TEI)+ := $work/tei:TEI;

<m:page>
    <xi:include href="/db/apps/mwjl-app/modules/header.xql"/>
    <xi:include href="/db/apps/mwjl-app/modules/body.xql"/>
    <xi:include href="/db/apps/mwjl-app/modules/footer.xql"/>
</m:page>

I would like to pass the variable $docPath to the three xi:include's, but when I format the xi:include as follows (for the footer, for example): <xi:include href="/db/apps/mwjl-app/modules/footer.xql?docPath={$docPath}"/>it ceases to produce results. If put a request:get-parameter statement on the target .xqls and include a fallback (so something like declare variable $docPath as xs:string := request:get-parameter('docPath','fallback') on the target xqls) it generates the fallback fine, so it's obvious to me that the function works. I'm just not forming my href correctly in the xi:include statements in the requesting code. But everything I've read suggests this should be how it's formed and I cannot for the life of me figure out where I'm going wrong. Am I mistaken that this is possible in eXist-db, and if I'm not how do I format the xi:include statement?


Solution

  • I would suggest applying the fn:encode-for-uri() function to the $docPath variable:

    <xi:include href="/db/apps/mwjl-app/modules/footer.xql?docPath={encode-for-uri($docPath)}"/>
    

    This function encodes any reserved characters in the supplied string by replacing them with their percent-encoded form. So paratext/Lydgate_Main.xml becomes paratext%2FLydgate_Main.xml.

    If this doesn't do the trick (sorry, I haven't tested it), I'd suggest adding logging to the target queries, e.g.:

    util:log("INFO", "docPath: " || request:get-parameter('docPath', 'no docPath parameter received'))
    

    ... which will be visible in your exist.log file when you next call your main query. (And then, if you could add a comment to this reply with, I'll update my suggestion accordingly.)