2016-06-11 6 views
0
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という属性から名前空間を削除したいと考えています。 SO <test ref='haha:123' type='hehe:456'/><test ref='123' type='456'/>になるはずです。私は以下の私が望む理想的な.xqyファイルで、正しい構文を知らない: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, 

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に書き戻されます。

+0

入力例を常に入力してください。質問に答える人の生活を楽にし、あなたの実際の問題に適切に答える答えを与えます。 –

+0

@JensEratあなたはすでにそれを持っています。 'test ref = 'haha:123' type = 'hehe:456' />'をコピーして '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)関数を知っています。したがって、機能を減らすことができます同時に、functx依存関係を削除しながら、あなたの関数を減らすことができます。

declare function local:stripNS($name as xs:string?) 
as xs:string? 
{ 
    if(contains($name, ':')) 
    then substring-after($name, ':') 
    else $name 
}; 

さらに、あなたも簡単なwhere句を使用すると、全体の機能を放棄することができます追加する(との数を減らし、最終的に

for $attribute in doc('test.xml')//(@ref, @type) 
return replace value of node $attribute with local:stripNS($attribute) 

にクエリを簡素化し、単一のクエリで複数の、異なる属性を選択することができます同時に属性を更新するため、大きなドキュメントのクエリが高速になります)。

for $attribute in doc('test.xml')//(@ref, @type) 
where contains($attribute, ':') 
return replace value of node $attribute with substring-after($attribute, ':') 
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 
関連する問題