2016-10-27 2 views
1

Я хочу, чтобы решить проблему - задана произвольная последовательность XML-пути, я хочу, чтобы создать структуру XML-дерева:Учитывая последовательность путей XML, создавать структуру XML дерева

например учитывая эту последовательность:

"/person/name" "/person/address" "/person/age" "/person/parent/name" 

генерации:

<person> 
<name></name> 
<address></address> 
<parent> 
<name></name> 
</parent> 
</person> 

Кто-нибудь знает хороший пример того, как сделать это в XQuery и/или XSLT?

Thanks

+0

Как вы можете ввести xslt? – Rao

ответ

4

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

declare function local:generate($paths) { 
    if(fn:empty($paths)) then() else 

    let $heads := $paths ! fn:subsequence(fn:tokenize(.,'/'),1,1) 
    let $tails := $paths ! fn:string-join(fn:subsequence(fn:tokenize(.,'/'),2),'/') 

    for $element in fn:distinct-values($heads) 
    return 
     if($element='') then local:generate($tails) 
     else element { xs:QName($element) } { 
      let $nextPaths := for $tail at $n in $tails where fn:starts-with($paths[$n],$element||'/') return $tail 
      return local:generate($nextPaths) 
     } 
}; 

local:generate(("/person/name", "/person/address", "/person/age", "/person/parent/name")) 
+0

Решение может быть улучшено в 3.1 с использованием массивов, которые позволяют представлять вложенные последовательности. –

+0

Спасибо, Бен, это работает очень хорошо! Я тоже посмотрю на предложение Майкла. – Robert

+0

Бен, ваша функция отлично работает, когда я передаю строку, как вы это делали. Однако, когда я пытаюсь передать вывод из функции, которую я имею, которая выводит строку в том же формате Я получаю сообщение об ошибке: XDMP-CAST: (err: FORG0001) xs: QName ($ element) - Недопустимый листинг : """ cast as xs: QName Почему не работает при передаче строки из моей функции, когда работает тот же вывод, если я вручную вставляю этот вывод в виде строки? – Robert