2016-06-11 9 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 

Ich möchte aus dem Wert des Attributs ref und type Namespace entfernen. SO <test ref='haha:123' type='hehe:456'/> sollte <test ref='123' type='456'/> werden. Ich weiß nicht, die richtige Syntax, unten ist die ideale .xqy Datei Ich möchte:BaseX: korrekte Syntax platzieren mehrere ‚ersetzen‘

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 

Aber natürlich enthält es Syntaxfehler:

[XUDY0017] Node can only be replaced once: attribute ref {"123"}.

$ basex -u test.xqy

Verwenden Sie den Befehl oben Prüfung. Die Ausgabe würde zurück auf geschrieben werden.

+0

Bitte geben Sie immer eine Beispieleingabe an. Erleichtert das Beantworten von Fragen und gibt Antworten, die besser zu Ihrem tatsächlichen Problem passen. –

+0

@JensErat Sie haben es schon. Kopieren Sie einfach die '' in eine lokale Datei mit dem Namen 'test.xml' –

+0

. Eine andere Sache noch wichtiger, die Sie verpasst haben: ** immer ** die Fehlermeldung enthalten, wenn Sie eine bekommen. Wenn Sie die Fehlermeldung gepostet hätten, hätten vermutlich die meisten XQuery-Leute das Problem sofort bemerkt, ohne den Code zu kopieren. –

Antwort

1

Das Problem Sie haben ist ein Tippfehler in der zweiten FLWOR Ausdruck: Sie versuchen, zweimal das gleiche Attribut zu ersetzen.

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 :) 

Wie auch immer, Ihre Abfrage ist zu komplex. Zunächst einmal, XQuery kennt eine substring-after($string, $token) Funktion, die Sie selbst umschreiben. So können Sie Ihre Funktion auf

0 reduzieren und gleichzeitig die functx Abhängigkeit entfernen.

Darüber hinaus können Sie auch mehrere, verschiedene Attribute mit einer einzigen Abfrage wählen, vereinfacht die Abfrage

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

schließlich das Hinzufügen einer einfachen where Klausel können Sie die ganze Funktion aufgeben (und Verringerung der Zahl der aktualisiert Attribute gleichzeitig, was die Suche nach großen Dokumenten beschleunigen würde):

for $attribute in doc('test.xml')//(@ref, @type) 
where contains($attribute, ':') 
return replace value of node $attribute with substring-after($attribute, ':') 
0

Die folgende Abfrage sollte die Arbeit machen:

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