Marklogic - Как назначить динамическую переменную в Xquery

Я пробовал упомянутый ниже XQuery.

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)

Фактический выход

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

Ожидаемый результат

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

Подскажите, пожалуйста, как изменить значение динамической переменной.


person Antony    schedule 28.03.2016    source источник


Ответы (1)


XQuery - это функциональный язык программирования, подразумевающий неизменность переменных. Вы не можете просто увеличивать или добавлять к определенной переменной. Обычно вместо этого для построения результата используется рекурсивная функция.

Эти примеры (есть более сжатые, я хотел, чтобы отдельные части были разделены и просты для понимания) рекурсивно создает путь, добавляя новый уровень каждый раз при выполнении. Префикс $path добавляется отдельно, чтобы не путать разные задачи.

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)

В этом конкретном случае альтернативой было бы перебрать счетчик позиций и соединить части до этой позиции:

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], '\'))
person Jens Erat    schedule 28.03.2016