调用BaseX REST API执行远程XQuery时http:send-request()报错求助
远程调用BaseX REST API执行XQuery的问题与解决方案
架构说明
- 服务器1:
- 部署有
test数据库 - BaseX REST API运行在端口
8080
- 部署有
- 服务器2:
- 仅包含BaseX应用代码
- 执行XQuery脚本
- 向服务器1发送REST请求以远程查询数据库
遇到的错误
所有POST请求均失败,常见报错如下:
[experr:HC0002] Conversion failed: "" (Line 1): Content is not allowed in prolog.
或:
[XPST0003] Empty query.
成功的GET请求示例
以下GET请求可正常访问REST端点:
let $DataServer := 'http://xx.xx.xx.xx:8080/rest/' let $httpTarget := fn:concat($DataServer,'test','/data/') let $res := ( http:send-request( <http:request method='get' username='admin' password='admin' send-authorization='true' href='{$httpTarget}' auth-method='Basic'> </http:request> ) )[2] return $res
返回结果:
<database xmlns="http://basex.org/rest" name="test"> <dir>...</dir> </database>
失败的POST请求示例
尝试POST执行XQuery的代码:
declare namespace http = "http://expath.org/ns/http-client"; let $query := "for $i in fn:uri-collection('bloomsbury/jobs/') return $i" let $res := http:send-request( <http:request method="post" href="http://xx.xxx.xxx.xxx:8080/rest" username="admin" password="admin" send-authorization="true"> <http:body media-type="application/x-www-form-urlencoded"> { "query=" || encode-for-uri($query) } </http:body> </http:request> ) return $res
仍收到报错:Content is not allowed in prolog
问题解答
1. 使用http:send-request()通过BaseX REST API发送XQuery的正确方式
BaseX REST API支持两种POST执行查询的有效方式,以下是修正后的代码示例:
方式一:XML格式请求体
declare namespace http = "http://expath.org/ns/http-client"; declare namespace rest = "http://basex.org/rest"; let $query := "for $i in fn:uri-collection('bloomsbury/jobs/') return $i" let $res := http:send-request( <http:request method="post" href="http://xx.xxx.xxx.xxx:8080/rest" username="admin" password="admin" send-authorization="true" media-type="application/xml"> <http:body> <rest:query> <rest:text>{$query}</rest:text> </rest:query> </http:body> </http:request> ) return $res[2]
方式二:application/x-www-form-urlencoded格式
需注意编码函数的正确性,避免过度编码导致BaseX无法解析:
declare namespace http = "http://expath.org/ns/http-client"; let $query := "for $i in fn:uri-collection('bloomsbury/jobs/') return $i" let $form-data := "query=" || encode-for-html-uri($query) let $res := http:send-request( <http:request method="post" href="http://xx.xxx.xxx.xxx:8080/rest" username="admin" password="admin" send-authorization="true" media-type="application/x-www-form-urlencoded"> <http:body>{$form-data}</http:body> </http:request> ) return $res[2]
2. 查询应该以XML还是application/x-www-form-urlencoded形式发送?
两种格式均被BaseX REST API支持,可根据场景选择:
- XML格式(
<query><text>结构):适合复杂场景,比如传递变量、配置序列化选项,语义清晰易扩展。 application/x-www-form-urlencoded格式:适合简单查询,请求体简洁,但需严格保证编码正确性。
3. 是否存在已知的编码/BOM问题导致该错误?
是的,常见触发原因包括:
- 编码函数误用:使用
encode-for-uri()处理整个查询字符串,会导致查询中的特殊字符(如空格、括号)被过度编码,BaseX无法识别,返回空查询或解析错误。 - 请求体含非法字符:如果请求体开头存在BOM(字节顺序标记)或多余空白字符,BaseX解析XML时会判定序言存在非法内容,触发
Content is not allowed in prolog错误。需确保请求体无冗余内容,且采用UTF-8无BOM编码。
内容的提问来源于stack exchange,提问作者Dharmendra Kumar Singh
相关产品推荐
相关产品推荐

