在 BaseX 中使用 XQuery XQUF 获取无更新表达式错误,以便在一个函数中进行 unknown/variable 次更新
Getting no updating expression error using XQuery XQUF in BaseX to make an unknown/variable number of updates in one function
由于技术上没有 "updating expression",此代码已停止执行 - 可能是因为它隐藏在 eval 字符串中,解释器看不到它。
我查看过的使用 xquery 更新工具的示例具有固定数量的更新语句,但我想在更新函数中处理可变数量的更新语句。
我可能偏离了(如果我是的话请告诉我)我是如何接近这个解决方案的,但我试图创建一个字符串,所有更新语句都以逗号分隔,然后 xquery:eval 字符串到在一个 return 语句中完成所有更新。
我认为这应该可行,因为该字符串看起来像如果我知道有多少我会硬编码的语句。
例如
return(将节点数量的值替换为'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))
};
顶部是我试图从休息电话开始工作的代码。底部是我要测试的代码,看看我是否能让它工作。这设置为 return 只是 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)
};
错误消息的原因(带有意外的拼写错误;感谢提示)是包含 xquery:eval
调用的函数被注释为 %updating
。然而,xquery:eval
函数是一个非更新函数。
XQuery 更新建议假定每个表达式必须是更新的或只读的。由于 xquery:eval
的参数在查询执行期间可能会发生变化……
for $query in ('123', 'delete node <a/>')
return xquery:eval($query)
…还有第二个函数xquery:eval-update
,可用于计算包含更新表达式的查询。如果您知道传入的查询将不会更新,只需删除 %updating
注释即可。
再补充一点:如果在查询中创建数据库,则不能在同一查询中请求其内容(单个 XQuery 是单个事务)。请查看 Pending Update List or have a look into the full specification.
上的简短文档
由于技术上没有 "updating expression",此代码已停止执行 - 可能是因为它隐藏在 eval 字符串中,解释器看不到它。
我查看过的使用 xquery 更新工具的示例具有固定数量的更新语句,但我想在更新函数中处理可变数量的更新语句。
我可能偏离了(如果我是的话请告诉我)我是如何接近这个解决方案的,但我试图创建一个字符串,所有更新语句都以逗号分隔,然后 xquery:eval 字符串到在一个 return 语句中完成所有更新。
我认为这应该可行,因为该字符串看起来像如果我知道有多少我会硬编码的语句。
例如
return(将节点数量的值替换为'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))
};
顶部是我试图从休息电话开始工作的代码。底部是我要测试的代码,看看我是否能让它工作。这设置为 return 只是 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)
};
错误消息的原因(带有意外的拼写错误;感谢提示)是包含 xquery:eval
调用的函数被注释为 %updating
。然而,xquery:eval
函数是一个非更新函数。
XQuery 更新建议假定每个表达式必须是更新的或只读的。由于 xquery:eval
的参数在查询执行期间可能会发生变化……
for $query in ('123', 'delete node <a/>')
return xquery:eval($query)
…还有第二个函数xquery:eval-update
,可用于计算包含更新表达式的查询。如果您知道传入的查询将不会更新,只需删除 %updating
注释即可。
再补充一点:如果在查询中创建数据库,则不能在同一查询中请求其内容(单个 XQuery 是单个事务)。请查看 Pending Update List or have a look into the full specification.
上的简短文档