【问题标题】:Writing one XQuery script in exist-db with support for multiple output formats在exist-db 中编写一个支持多种输出格式的XQuery 脚本
【发布时间】:2014-08-22 22:25:40
【问题描述】:

这是

的后续问题

Getting hold of tag content in XQuery 3.0 (exist-db)

假设这样的 xquery 脚本应该能够根据类似的查询参数以 XML、JSON 或 HTML 格式返回结果

http://host/exist/rest/db/myscript.xql?mode=xml|html|json

我知道如何从 XML 更改序列化程序 -> JSON 以及如何应用 使用 transform:transform() 进行 XSLT 转换。

为结果封装 XML 生成然后根据请求参数将其转换为一种输出格式的最佳方法是什么?

xquery version "3.0";

module namespace services = "http://my/services";

import module namespace transform = "http://exist-db.org/xquery/transform";
declare namespace rest = "http://exquery.org/ns/restxq";
declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";

declare
    %rest:GET
    %rest:path("/data.html")
    %output:media-type("text/html")
    %output:method("html5")
function services:home() {
    transform:transform(services:example1(), doc("/db/my-xml-to-html.xslt"), ())
};

declare
    %rest:GET
    %rest:path("/data.json")
    %rest:produces("application/json")
    %output:method("json")
function services:home-json() {
  services:example1()
};

declare
    %rest:GET
    %rest:path("/data.xml")
    %rest:produces("application/xml")
function services:home-xml() {
  services:example1()
};

declare
    %private
function services:example1() {
    <some>
       <data>hello world</data>
    </some>
};

【问题讨论】:

    标签: xquery exist-db


    【解决方案1】:

    我建议看一下 eXist 中的 RESTXQ,因为这使您可以根据内容协商或任何其他 HTTP 参数或标头轻松控制结果格式。例如使用内容协商来生成 XML、JSON 和 HTML 表现形式:

    xquery version "3.0";
    
    module namespace services = "http://my/services";
    
    import module namespace transform = "http://exist-db.org/xquery/transform";
    declare namespace rest = "http://exquery.org/ns/restxq";
    declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
    
    declare
        %rest:GET
        %rest:path("/data")
        %rest:produces("text/html")
        %output:method("html5")
    function services:home() {
        transform:transform(services:example1(), doc("/db/my-xml-to-html.xslt"), ())
    };
    
    declare
        %rest:GET
        %rest:path("/data")
        %rest:produces("application/json")
        %output:method("json")
    function services:home-json() {
      services:example1()
    };
    
    declare
        %rest:GET
        %rest:path("/data")
        %rest:produces("application/xml")
    function services:home-xml() {
      services:example1()
    };
    
    declare
        %private
    function services:example1() {
        <some>
           <data>here</data>
        </some>
    };
    

    【讨论】:

    • 如果您想基于 URI 进行内容协商,而不是像上面那样使用 Accept HTTP 标头,您可以改为执行类似的操作 - 声明 %rest:GET %rest:path(" /data.html") %output:method("html5") %output:media-type("text/html") function services:home() { (: etc... :)
    • 我从配置中得出,上面脚本的位置无关紧要。在这种情况下,对host:port//exist/rest/db/data.html(或原始代码的 /data)的 HTTP GET 应该返回 ... 片段?但是,这不起作用。服务器只返回一个带有空有效负载的 200 响应。 RestXqTrigger 在 /db/system/config/db/collection.xconf 中启用
    • @user3790407 如果我没记错的话,eXist 默认将 RestXQ 映射到 exist/restxq,所以你的 URL 看起来像 http://host:port/exist/restxq/data
    • 不直接..查看我上面的 RESTXQ 代码的更新。调用host.port/exist/restxq/data.html 给我:HTTP ERROR 405 访问/exist/restxq/data.html 时出现问题。原因:此 URL 不支持 HTTP 方法 GET
    • @AndreasJung 我认为理想情况下您应该为此提出一个新问题,因为现在您的问题没有多大意义。但是,您应该查阅 restxq 日志文件以了解您的查询是否被添加到注册表中。
    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多