XQuery - динамически поменять местами атрибуты и значения элементов (обратная структура)
Итак, у меня есть это (необычное) задание
"Напишите запрос, который инвертирует все подэлементы элемента / music, так что их собственные подэлементы становятся атрибутами, а их атрибуты становятся подэлементами. Для тех подэлементов, которые не имеют своих подэлементов, их содержимое данных должно стать атрибутом с имя "значение"."
где я использую эту базу данных: https://gist.githubusercontent.com/Schytheron/0a5c4756db62a1f43fc40226659c12cf/raw/71378ab9cede19e3f5bb33e948177a9fccfcc132/songs.xml и я действительно даже не знаю, с чего начать. Я полностью потерян. Может ли это быть решено только рекурсивно или есть другой способ (потому что я никогда не пытался делать рекурсию в Xquery)? Есть ли у вас какие-либо советы / стратегии для решения этой или каких-либо полезных функций (я очень плохо знаком с Xquery, поэтому не знаю, сколько полезных функций) я могу использовать?
Мысли? Идеи?
Спасибо!
РЕДАКТИРОВАТЬ: Просто чтобы прояснить ситуацию. Я знаю, что, вероятно, я могу просто сделать это вручную для каждого элемента и их дочерних элементов с количеством вложенных циклов for x, но я хочу знать, есть ли способ сделать это динамическим, чтобы он работал с ЛЮБОЙ базой данных XML.
1 ответ
Для ограниченного случая использования преобразования дочернего элемента корневого элемента вы можете использовать некоторые функции:
declare function local:transform($element as element()) as element() {
element {name($element)} {
$element/node() ! local:attribute(.),
$element/@* ! local:element(.)
}
};
declare function local:attribute($node as node()) as attribute() {
typeswitch ($node)
case element() return attribute {name($node)} {data($node) }
case text() return attribute value { $node }
default return ()
};
declare function local:element($att as attribute()) as element() {
element {name($att)} { data($att) }
};
/*!element {name()} { *!local:transform(.) }