BaseX:正确的语法来放置多个'replace'

时间:2016-06-11 15:54:18

标签: xquery basex

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

我想从reftype属性的值中删除名称空间。因此<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

2 个答案:

答案 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