在exist-db 中编写一个支持多种输出格式的XQuery 脚本

Posted

技术标签:

【中文标题】在exist-db 中编写一个支持多种输出格式的XQuery 脚本【英文标题】:Writing one XQuery script in exist-db with support for multiple output formats 【发布时间】: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>
;

【问题讨论】:

【参考方案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 日志文件以了解您的查询是否被添加到注册表中。

以上是关于在exist-db 中编写一个支持多种输出格式的XQuery 脚本的主要内容,如果未能解决你的问题,请参考以下文章

试图与exist-db 5.3.0 版本制造一场战争

超给力,抛弃手动维护,一键生成数据库文档支持多种格式!

以多种格式输出数据库信息

在Android 4.x中显示矢量图形

如何在 eXide (eXist-db) 中显示超过 10 个结果?

360浏览器中有啥好用的获取视频的扩展程序吗