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]节点只能替换一次:属性ref {“123”}。
$ basex -u test.xqy
使用上面的命令进行测试。输出将写回test.xml
。
答案 0 :(得分:1)
您遇到的问题是第二个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依赖项。
此外,您还可以使用单个查询选择多个不同的属性,从而将查询简化为
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, ':')
答案 1 :(得分:0)
以下查询应该完成这项工作:
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