如何在eXist-db中的函数之间共享标记片段?

时间:2016-01-26 12:22:26

标签: xquery exist-db

我想知道是否有办法在eXist-db中共享html代码片段。我有两个不同的(更多预期的后期)函数返回相同的大html表单以获得不同的结果。当我在其中一个中更改某些内容时,维护相同的代码很烦人。我试过了:

  1. 像html文件一样保存它并使用doc()函数加载它(eXist抱怨它不是xml文件,它是二进制文件。
  2. 将它像全局变量一样保存到一个单独的模块中(eXist抱怨上下文存在问题)。我不知道如何在没有名称空间前缀的情况下传递这样的变量。
  3. 将它保存为返回其自身巨大变量的函数(eXist抱怨上下文存在问题)。
  4. 最佳做法是什么?

    更新

    好吧,我试图将代码片段放入变量 insinde 作为模块加载的函数。对我来说,这似乎是合理的。但是,当我尝试返回时出现错误:

    err:XPDY0002 Undefined context sequence for 'child::snip:snippet' [at line 62, column 13, source: /db/apps/karolinum-apps/modules/app.xql]
    In function:a pp:book-search(node(), map, xs:string?) [34:9:/db/apps/karolinum-apps/modules/app.xql]
    

    我这样称呼它:

    declare function app:list-books($node as node(), $model as map(*)) {
        for $resource in collection('/db/apps/karolinum-apps/data/mono')
        let $author := $resource//tei:titleStmt/tei:author/text()
        let $bookName := $resource//tei:titleStmt/tei:title/text()
        let $bookUri := base-uri($resource)
        let $imgPath := replace($bookUri, '[^/]*?$', '')
        let $fileUri := ( '/exist/rest' || $bookUri )
        let $fileName := replace($bookUri, '.*?/', '')
        return
            if ($resource//tei:titleStmt/tei:title)
            then
                snip:snippet
            else ()
    };
    

    请问任何想法?

    更新II

    这里我有模块中的功能:

    module namespace snip = "http://46.28.111.241:8081/exist/db/apps/karolinum-apps/modules/snip";
    
    declare function snip:snippet($node as node(), $model as map(*), $author as xs:string, $bookTitle as xs:string, $bookUri as xs:anyURI, $fileUri as xs:anyURI) as element()* {
        let $snippet := 
            (
                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h3 class="panel-title"><a href="{$fileUri}">{$bookTitle}</a> ({$author})</h3>
                    </div>
                    <div class="panel-body">
                    ...
                    </div>
            )
            return $snippet
    };
    

    我试图称之为:

    declare function app:list-books($node as node(), $model as map(*)) {
        for $resource in collection('/db/apps/karolinum-apps/data/mono')
        let $author := $resource//tei:titleStmt/tei:author/text()
        let $bookTitle := $resource//tei:titleStmt/tei:title/text()
        let $bookUri := base-uri($resource)
        let $fileUri := ('/exist/rest' || $bookUri)
        let $fileName := replace($bookUri, '.*?/', '')
        where not(util:is-binary-doc($bookUri))
        order by $bookTitle, $author
        return
            snip:snippet($author, $bookTitle, $bookUri, $fileUri)
    };
    

    它抛出:

    err:XPST0017 error found while loading module app: Error while loading module app.xql: Function snip:snippet() is not defined in namespace 'http://46.28.111.241:8081/exist/db/apps/karolinum-apps/modules/snip' [at line 35, column 9]
    

    当我尝试将代码段放入变量时,无法传递使用的局部变量(它抛出$fileUri is not set)。除此之外,我尝试更改返回的类型element()*,但没有任何帮助。

2 个答案:

答案 0 :(得分:1)

您的所有方法都应该有效。让我解释一下:

  1. HTML代码段是否格式良好?如果是这样,请将其另存为form.xmlform.html(因为默认情况下,eXist假定扩展名为.html的文件格式正确;请参阅eXist安装中的mime-types.xml文件夹)并用doc($path)引用它。如果格式不正确,您可以将其另存为form.txt,然后使用util:binary-to-string(util:binary-doc($path))将其保存。或者使HTML格式良好并使用第一种替代方案。

  2. 这也是有效的,因此您不能正确地声明或引用全局变量。你得到的确切错误是什么?你能发布一个我们可以运行的小例子片段来重现你的结果吗?

  3. 见#2。

答案 1 :(得分:1)

我很亲密。有必要以某种方式将参数传递给嵌套函数,并省略eXist的典型$node as node(), $model as map(*)作为参数。

模板功能:

declare function app:list-books($node as node(), $model as map(*)) {
    for $resource in collection('/db/apps/karolinum-apps/data/mono')
    let $author := $resource//tei:titleStmt/tei:author/text()
    let $bookTitle := $resource//tei:titleStmt/tei:title/text()
    let $bookUri := base-uri($resource)
    let $bookId := xs:integer(util:random() * 10000)
    let $fileUri := ('/exist/rest' || $bookUri)
    let $fileName := replace($bookUri, '.*?/', '')
    where not(util:is-binary-doc($bookUri))
    order by $bookTitle, $author
    return
        snip:snippet($author, $bookTitle, $bookUri, $bookId, $fileUri)
};

代码段功能:

declare function snip:snippet($author as xs:string, $bookTitle as xs:string, $bookUri as xs:anyURI, $bookId as xs:string, $fileUri as xs:anyURI) as element()* {
    let $snippet := 
        (
            <div class="panel panel-default">
            ...
           </div>
       )
   return $snippet
};