此代码在其轨道中停止,因为技术上没有"更新表达式" - 可能是因为它隐藏在一个eval字符串中,并且解释器没有看到它。
我所评论的使用xquery更新工具的示例具有固定数量的更新语句,但我想在更新函数中处理可变数量的更新语句。
我可能会离开(请告诉我,如果我)我如何处理此解决方案,但我尝试创建一个字符串,所有更新语句以逗号分隔,然后xquery:eval字符串以执行所有操作一个返回语句中的更新。
我认为这应该有效,因为字符串看起来像我会硬编码的语句,如果我知道多少 例如 返回(用' 1'替换节点数量的值, 用' new_market')替换节点市场的价值
Stopped at C:/Program Files (x86)/BaseX/webapp/product.xqm, 109/7:
[XUST0002] Function body is no an updating expression.
(looks like a typo in the error message btw)
(: example new data values
$req - could be any number of nodes with new values
<request>
<data>
<ID>1</ID>
<quantity>1</quantity>
<market>new_market</market>
</data>
</request>
:)
(: Old data that matches ID and needs replacing
<csv>
<record>
<ID>1</ID>
<quantity>3</quantity>
<market>old_market</market>
</record>
<csv>
:)
declare
%rest:path("updy/{$db}/{$resource}")
%rest:POST("{$req}")
%updating function page:updy($db,$resource,$req as document-node())
{
let $input := concat("db:open('",$db,"','",$resource,"')")
for $node_name in $req/request/data/(* except ID)/name()
let $updating_record := query:eval($input)/csv/record[ID=$req/request/data/ID]
for $updating_fields in $updating_record//*[name()=$node_name]
let $to_value := $req/request/data/*[name()=$updating_fields/name()]/data()
let $eval_string := string-join(concat("replace value of node ",$updating_fields/name()," with '",$to_value,"'")," , ")
return xquery:eval($eval_string))
};
顶部是我试图通过休息呼叫工作的代码。底部是我试图测试的代码,看看我是否可以让它工作。这被设置为仅返回eval字符串,然后在那里切换注释以尝试运行它。
declare %private updating function local:updy($db,$resource,$req as element())
{
let $input := concat("db:open('",$db,"','",$resource,"')")
for $node_name in $req//data/(* except ID)/name()
let $updating_record := xquery:eval($input)/csv/record[ID=$req//data/ID]
for $updating_fields in $updating_record//*[name()=$node_name]
let $to_value := $req//data/*[name()=$updating_fields/name()]/data()
let $eval_string := string-join(concat("replace value of node ",$updating_fields/name()," with '",$to_value,"'")," , ")
(: return $eval_string :)
return xquery:eval($eval_string)
};
(: example new data values :)
(: $req - could be any number of nodes with new values :)
let $req :=
<request>
<data>
<ID>1</ID>
<quantity>1</quantity>
<market>new_market</market>
</data>
</request>
(: Old data that matches ID and needs replacing :)
let $input :=
<csv>
<record>
<ID>1</ID>
<quantity>3</quantity>
<market>old_market</market>
</record>
</csv>
let $dbadd := db:create("ProductTest", $input, "exportDataTest.csv")
return local:updy("ProductTest","exportDataTest.csv",$req)
我在下面添加了完成的代码,因为在我收到的帮助下,我能够让它正常工作。
declare
%rest:path("updz/{$db}/{$resource}")
%rest:POST("{$req}")
%updating function page:updz($db,$resource, $req as document-node()) {
let $input := concat("db:open('",$db,"','",$resource,"')")
let $the_id := $req//data/ID
let $update_string :=
for $node_name in $req//data/(* except ID)/name()
let $updating_record := xquery:eval($input)/csv/record[ID=$req//data/ID]
for $updating_fields in $updating_record//*[name()=$node_name]
let $to_value := $req//data/*[name()=$updating_fields/name()]/data()
return string-join(concat("replace value of node ", $input,"/csv/record[ID='",$the_id,"']//",$updating_fields/name()," with '",$to_value,"'")," , ")
let $final_update_string := concat("(",string-join($update_string,","),",update:output(<response><status>1</status></response>))")
(: return $final_update_string :)
return xquery:eval-update($final_update_string)
};
答案 0 :(得分:1)
错误消息(带有意外错字;感谢提示)的原因是包含xquery:eval
调用的函数注释为%updating
。但是,xquery:eval
函数是一个非更新函数。
XQuery Update Recommendation假定每个表达式必须是更新或只读。由于xquery:eval
的参数在查询执行期间可能会有所不同......
for $query in ('123', 'delete node <a/>')
return xquery:eval($query)
...有一个名为xquery:eval-update
的第二个函数,可用于评估包含更新表达式的查询。如果您知道传入的查询将不会更新,只需删除%updating
注释。
还有一条评论:如果在查询中创建数据库,则无法在同一查询中请求其内容(单个XQuery是单个事务)。请查看Pending Update List上的简短文档,或查看full specification。