3

Environment: eXist-db 4.2.1 , XQuery 3.1

I have built a number functions in eXist which output HTML results fine as functions on their own (when I pass the parameters directly). As an example, this little function (document:doc-sidebar-sub4 in /modules/document.xql):

module namespace document="/db/apps/fooapp/modules/document";
declare namespace templates="http://exist-db.org/xquery/templates";


import module namespace common="/db/apps/fooapp/modules/common" at "/db/apps/fooapp/modules/common.xql";

declare function document:doc-sidebar-sub4(
$node as node(), 
$model as map(*), 
$currentdoc as xs:string)

{
    let $sidebar :=
        (<div class="sidebar-sub-4">
                <p><span class="en">To cite this document:</span></p>
                <p>{common:cite-doc($currentdoc,"html")}</p>
        </div>)
    return $sidebar                 
 };

Produces a little snippet of HTML derived from document foo-doc_0099.xml (by calling another function):

<div class="sidebar-sub-4">
 <p><span class="en">To cite this document:</span></p>
 <p><span>Joe Smith. <i>Digital Edition of some old manuscript</i>. 
 http://www.foosite.fr/foo-doc_0099.xml. Retrieved 2018-10-14.</span> 
 </p>
</div>

I am now trying to include this snippet in my main document.html (with document hard coded in the parameter - eventually to be got from HTTP request) with this div:

<div data-template="templates:include" 
      data-template-with="document:doc-sidebar-sub4" 
      data-template-currentdoc="foo-doc_0099.xml"/>

But it produces the following error:

exerr:ERROR XPTY0004: The actual cardinality for parameter 3 does not match the cardinality declared in the function's signature: templates:include($node as node(), $model as map, $path as xs:string) item()*. Expected cardinality: exactly one, got 0. [at line 219, column 14, source: /Users/foo/Library/Application Support/org.exist/expathrepo/shared-0.4.2/content/templates.xql]


Another version of the same template call produces a different error:

<div data-template="templates:include" 
        data-template-with="document:doc-sidebar-sub4" 
        data-template-path="modules/document.xql"
        data-template-currentdoc="foo-doc_0099.xml"/>

Error:

err:FODC0005 exerr:ERROR Document /db/apps/fooapp/modules/document.xql is a binary resource, not an XML document. Please consider using the function util:binary-doc() to retrieve a reference to it. [at line 436, column 27, source: /Users/foou/Library/Application Support/org.exist/expathrepo/shared-0.4.2/content/templates.xql]

I tried to follow the demos, various tutorials, and answers including this, but can't seem to identify the problem.


Another version, different error. This call

<div data-template="document:doc-sidebar-sub4" data-template-path="modules/document.xql":>

Produces:

templates:NotFound No template function found for call document:doc-sidebar-sub4 [at line 189, column 85, source: /Users/foo/Library/Application Support/org.exist/expathrepo/shared-0.4.2/content/templates.xql]

Many thanks in advance for any help for this learner.

Edit: added adjustments from @joewiz, other errors is returned

jbrehr
  • 775
  • 6
  • 19

2 Answers2

2

Functions that you call via eXist's HTML templating facility must have two required parameters: $node as node(), $model as map(*), before any named parameters like your $currentdoc parameter. To fix your problem, you need to add these two parameters to your function signature, as follows:

declare function document:doc-sidebar-sub4(
    $node as node(), 
    $model as map(*), 
    $currentdoc as xs:string
)
{
    let $sidebar :=
        (<div class="sidebar-sub-4">
                <p><span class="en">To cite this document:</span></p>
                <p>{common:cite-doc($currentdoc,"html")}</p>
        </div>)
    return $sidebar                 
};

The section of the Templating documentation on "Templating Functions" at https://exist-db.org/exist/apps/doc/templating#D3.19 explains what these two required parameters are for.

Joe Wicentowski
  • 5,159
  • 16
  • 26
  • I updated the code but it produces the exact same error. I've updated my post above with the fuller error. – jbrehr Oct 15 '18 at 05:22
  • I made a second attempt with revised template call and it gave a new error `document.xql is a binary resource, not an XML document`. I've updated the post with info. – jbrehr Oct 15 '18 at 10:04
  • 1
    Oh! Skip the template:include call and directly call your function: `data-template=“document-sidebar”` – Joe Wicentowski Oct 15 '18 at 11:12
  • This produces a new error `templates:NotFound No template function found for call document:doc-sidebar-sub4` based on both call variants `
    ` and `
    `
    – jbrehr Oct 15 '18 at 11:27
  • 1
    The path parameter should be removed, but did you include the currentdoc parameter? Is the document module included in the modules imported into view.xql? – Joe Wicentowski Oct 15 '18 at 11:30
  • OK, I've just put the document model into view.xql and it worked (with the parameter). – jbrehr Oct 15 '18 at 11:35
0

Putting a full answer here for future search engine indexing. The errors being produced were:

  • exerr:ERROR XPTY0004: The actual cardinality for parameter 3 does not match the cardinality declared in the function's signature
  • err:FODC0005 exerr:ERROR Document ..... is a binary resource, not an XML document.
  • templates:NotFound No template function found for call

To solve this, the function looks like this:

 module namespace document="/db/apps/fooapp/modules/document";
 declare namespace templates="http://exist-db.org/xquery/templates";

 import module namespace common="/db/apps/fooapp/modules/common" at "/db/apps/fooapp/modules/common.xql";

 declare function document:doc-sidebar-sub4(
    $node as node(), 
    $model as map(*), 
    $currentdoc as xs:string)
 {
 let $sidebar :=
    (<div class="sidebar-sub-4">
            <p><span class="en">To cite this document:</span></p>
            <p>{common:cite-doc($currentdoc,"html")}</p>
    </div>)
 return $sidebar                 
 };

The template call is quite simple (includes parameter if required):

<div data-template="document:doc-sidebar-sub4" data-template-currentdoc="foo-doc.xml"/>

But for this to work, the module needs to be imported into the module view.xql:

import module namespace document="/db/apps/fooapp/modules/document" at "/db/apps/fooapp/modules/document.xql";
jbrehr
  • 775
  • 6
  • 19