2016-03-28 6 views
1

Ich habe versucht, unten genannten XQuery.Marklogic - Wie dynamische Variable in Xquery zuweisen

declare variable $path as xs:string :="D:\Mongo\"; 

    let $uri :="/MJ/1932/Vol1/Part1/387.xml" 
    let $x := fn:normalize-space(fn:replace($uri,"/"," ")) 
    for $i in fn:tokenize($x, " ") 
    let $j := fn:concat($path,$i) 
    return($j) 

Tatsächliche Ausgabe

D:\Mongo\MJ 
    D:\Mongo\1932 
    D:\Mongo\Vol1 
    D:\Mongo\Part1 
    D:\Mongo\387.xml 

Erwartete Ausgabe

D:\Mongo\MJ 
D:\Mongo\MJ\1932 
D:\Mongo\MJ\1932\Vol1 
D:\Mongo\MJ\1932\Vol1\Part1 
D:\Mongo\MJ\1932\Vol1\Part1\387.xml 

Bitte empfehlen Sie mir, wie der dynamisch variablen Wert zu ändern.

Antwort

4

XQuery ist eine funktionale Programmiersprache, die impliziert, dass Variablen unveränderlich sind. Sie können nicht einfach an eine definierte Variable inkrementieren oder anhängen. In der Regel wird stattdessen eine rekursive Funktion verwendet, um das Ergebnis zu konstruieren.

Diese Beispiele (es gibt prägnantere, ich wollte die einzelnen Teile getrennt und einfach zu verstehen) erstellt rekursiv den Pfad und fügt bei jeder Ausführung eine andere Ebene hinzu. Das Präfix $path wird separat angehängt, um die verschiedenen Aufgaben nicht zu verwechseln.

declare variable $path as xs:string :="D:\Mongo\"; 
declare variable $uri as xs:string := "/MJ/1932/Vol1/Part1/387.xml"; 

declare function local:add-path($parts as xs:string*) as xs:string* { 
    let $head := $parts[1] 
    let $tail := $parts[position() > 1] 
    return 
    if ($head) 
    then (
     $head, 
     for $path in local:add-path($tail) 
     return string-join(($head, $path), "\") 
    ) 
    else() 

}; 

for $uri in local:add-path(fn:tokenize(fn:normalize-space(fn:replace($uri,"/"," ")), " ")) 
return concat($path, $uri) 

In diesem speziellen Fall eine Alternative zur Schleife über einen Positionszähler sein würde und die Teile dieser Position verbinden:

declare variable $path as xs:string :="D:\Mongo\"; 
declare variable $uri as xs:string := "/MJ/1932/Vol1/Part1/387.xml"; 

let $parts := fn:tokenize(fn:normalize-space(fn:replace($uri,"/"," ")), " ") 
for $i in (1 to count($parts)) 
return concat($path, string-join($parts[position() <= $i], '\')) 
+0

Dank Jens Erat, seine Arbeit gut. – Antony