как изменить структуру XML с помощью XQuery

У меня есть файл XML, содержащий имя сотрудников и выполненную ими работу. Структура файла XML -

<Employee>AAA@A#B#C#D</Employee>
<Employee>BBB@A#B#C#D</Employee>
<Employee>CCC@A#B#C#D</Employee>
<Employee>DDD@A#B#C#D</Employee>

Есть тысячи записей, и я должен изменить структуру на -

<Employee>
  <Name>AAA</Name>
  <Jobs>
   <Job>A</Job>
   <Job>B</Job>
   <Job>C</Job>
   <Job>D</Job>
  </Jobs>
</Employee>

Как это сделать с помощью XQuery в BaseX?


person Community    schedule 23.12.2013    source источник


Ответы (2)


3 функции XQuery, substring-before, substring-after и tokenize, используются для получения требуемого вывода.

substring-before используется для получения имени.

Точно так же substring-after используется для получения части задания.

Затем функция tokenize используется для разделения заданий.

let $data :=
  <E>
    <Employee>AAA@A#B#C#D</Employee>
    <Employee>BBB@A#B#C#D</Employee>
    <Employee>CCC@A#B#C#D</Employee>
    <Employee>DDD@A#B#C#D</Employee>
  </E>


for $x in $data/Employee
return 

<Employee>
   {<Name>{substring-before($x,"@")}</Name>}
   {<Jobs>{
   for $tag in tokenize(substring-after($x,"@"),'#')
   return 
     <Job>{$tag}</Job>
   }</Jobs>
}</Employee>

ХТХ...

person John    schedule 23.12.2013

Токенизация строки, вероятно, проще и быстрее. tokenize($string, $pattern) разбивает $string с помощью регулярного выражения $pattern, head($seq) возвращает первое значение последовательности, а tail($seq) все, кроме первого. Конечно, вы также можете использовать позиционные предикаты, но эти функции легче читать.

for $employee in //Employee
let $tokens := tokenize($employee, '[@#]')
return element Employee {
  element Name { head($tokens) },
  element Jobs {
    for $job in tail($tokens)
    return element Job { $job }
  }
}
person Jens Erat    schedule 23.12.2013