BaseX:放置多个 'replace ' 的正确语法
BaseX: correct syntax to place multiple 'replace '
declare function local:stripNS($name as xs:string?)
as xs:string?
{
if(contains($name, ':'))
then substring($name, functx:index-of-string($name, ':') + 1)
else $name
};
for $x in doc("test.xml")//*[@ref]
let $tmp:=local:stripNS($x/@ref)
return replace value of node $x/@ref with $tmp
我想从 ref
和 type
属性的值中删除命名空间。所以 <test ref='haha:123' type='hehe:456'/>
应该变成 <test ref='123' type='456'/>
。我不知道正确的语法,下面是我想要的理想 .xqy 文件:
declare function local:stripNS($name as xs:string?)
as xs:string?
{
if(contains($name, ':'))
then substring($name, functx:index-of-string($name, ':') + 1)
else $name
};
for $x in doc('test.xml')//*[@ref]
let $tmp:=local:stripNS($x/@ref)
return replace value of node $x/@ref with $tmp,
for $x in doc('test.xml')//*[@type]
let $tmp:=local:stripNS($x/@type)
return replace value of node $x/@ref with $tmp
但显然它包含语法错误:
[XUDY0017] Node can only be replaced once: attribute ref {"123"}.
$ basex -u test.xqy
使用上面的命令进行测试。输出将写回 test.xml
.
下面的查询应该可以完成这项工作:
declare function local:stripNS($name as xs:string) as xs:string {
replace($name, "^.*:", "")
};
for $attr in doc('test.xml')//*/(@ref, @type)
let $tmp := local:stripNS($attr)
return replace value of node $attr with $tmp
您遇到的问题是第二个 flwor 表达式中的拼写错误:您尝试两次替换同一属性。
for $x in doc('test.xml')//*[@type]
let $tmp:=local:stripNS($x/@type)
return replace value of node $x/@ref with $tmp
(: ^^^^ should be @type :)
无论如何,您的查询过于复杂。首先,XQuery 知道您正在重写的 substring-after($string, $token)
函数。所以你可以把你的功能缩减到
declare function local:stripNS($name as xs:string?)
as xs:string?
{
if(contains($name, ':'))
then substring-after($name, ':')
else $name
};
同时删除 functx 依赖项。
此外,您还可以 select 使用单个查询的多个不同属性,将查询简化为
for $attribute in doc('test.xml')//(@ref, @type)
return replace value of node $attribute with local:stripNS($attribute)
最后,添加一个简单的where
子句让你放弃整个功能(同时减少更新属性的数量,这将加快大文档的查询):
for $attribute in doc('test.xml')//(@ref, @type)
where contains($attribute, ':')
return replace value of node $attribute with substring-after($attribute, ':')
declare function local:stripNS($name as xs:string?)
as xs:string?
{
if(contains($name, ':'))
then substring($name, functx:index-of-string($name, ':') + 1)
else $name
};
for $x in doc("test.xml")//*[@ref]
let $tmp:=local:stripNS($x/@ref)
return replace value of node $x/@ref with $tmp
我想从 ref
和 type
属性的值中删除命名空间。所以 <test ref='haha:123' type='hehe:456'/>
应该变成 <test ref='123' type='456'/>
。我不知道正确的语法,下面是我想要的理想 .xqy 文件:
declare function local:stripNS($name as xs:string?)
as xs:string?
{
if(contains($name, ':'))
then substring($name, functx:index-of-string($name, ':') + 1)
else $name
};
for $x in doc('test.xml')//*[@ref]
let $tmp:=local:stripNS($x/@ref)
return replace value of node $x/@ref with $tmp,
for $x in doc('test.xml')//*[@type]
let $tmp:=local:stripNS($x/@type)
return replace value of node $x/@ref with $tmp
但显然它包含语法错误:
[XUDY0017] Node can only be replaced once: attribute ref {"123"}.
$ basex -u test.xqy
使用上面的命令进行测试。输出将写回 test.xml
.
下面的查询应该可以完成这项工作:
declare function local:stripNS($name as xs:string) as xs:string {
replace($name, "^.*:", "")
};
for $attr in doc('test.xml')//*/(@ref, @type)
let $tmp := local:stripNS($attr)
return replace value of node $attr with $tmp
您遇到的问题是第二个 flwor 表达式中的拼写错误:您尝试两次替换同一属性。
for $x in doc('test.xml')//*[@type]
let $tmp:=local:stripNS($x/@type)
return replace value of node $x/@ref with $tmp
(: ^^^^ should be @type :)
无论如何,您的查询过于复杂。首先,XQuery 知道您正在重写的 substring-after($string, $token)
函数。所以你可以把你的功能缩减到
declare function local:stripNS($name as xs:string?)
as xs:string?
{
if(contains($name, ':'))
then substring-after($name, ':')
else $name
};
同时删除 functx 依赖项。
此外,您还可以 select 使用单个查询的多个不同属性,将查询简化为
for $attribute in doc('test.xml')//(@ref, @type)
return replace value of node $attribute with local:stripNS($attribute)
最后,添加一个简单的where
子句让你放弃整个功能(同时减少更新属性的数量,这将加快大文档的查询):
for $attribute in doc('test.xml')//(@ref, @type)
where contains($attribute, ':')
return replace value of node $attribute with substring-after($attribute, ':')