Для смежных элементов вы можете tumbling window
предложение https://www.w3.org/TR/xquery-31/#id-tumbling-windows:
declare variable $countries as xs:string* := ('Australia', 'India', 'USA');
<root>
{
for tumbling window $w in root/*
start $s when true()
end next $n when ($s = $countries) and not($n = $countries) or (not($s = $countries) and $n = $countries)
return
if ($w[1] = $countries)
then <Country>
{$w}
</Country>
else $w
}
</root>
https://xqueryfiddle.liberty -development.net / gWcDMeh / 2
Если вы хотите обернуть, основываясь на именах элементов, тогда с предложением window вы можете использовать
declare variable $countries as xs:QName* := (QName('', 'value5'), QName('', 'value6'), QName('', 'value7'));
<root>
{
for tumbling window $w in root/*
start $s when true()
end next $n
when ($s/node-name() = $countries) and not($n/node-name() = $countries)
or (not($s/node-name() = $countries) and $n/node-name() = $countries)
return
if ($s/node-name() = $countries)
then <Country>
{$w}
</Country>
else $w
}
</root>
https://xqueryfiddle.liberty -development.net / gWcDMeh / 6
Теперь я также попытался избежать использования предложения window
и вместо этого реализовал обтекание с помощью рекурсивной функции:
declare variable $countries as xs:string* := ('Australia', 'India', 'USA');
declare function local:wrap($seq as item()*, $wrapper as element()) as item()*
{
let $first-item := head($seq)
return
if (not($first-item))
then (if (empty($wrapper/node())) then () else $wrapper)
else if (not($first-item[. = $countries]))
then
(if (empty($wrapper/node())) then () else $wrapper,
$first-item,
local:wrap(tail($seq), $wrapper!element {node-name()} {})
)
else local:wrap(tail($seq), $wrapper!element {node-name()} { node(), $first-item})
};
<root>
{
local:wrap(root/*, <countries/>)
}
</root>
Похоже, что делать эту работу также в https://xqueryfiddle.liberty -development.net / gWcDMeh / 4 , я не знаю, имеет ли это смысл с Marklogic. Если вы хотите выполнить перенос на основе имен элементов, а не значений, вы можете адаптировать код к https://xqueryfiddle.liberty -development.net / gWcDMeh / 5 , который объявляет
declare variable $countries as xs:QName* := (QName('', 'value5'), QName('', 'value6'), QName('', 'value7'));
и затем сравнивает else if (not($first-item/node-name() = $countries))
.
Если вам нужно только обернуть все элементы value5
, value6
, value7
, тогда я думаю, что вы можете просто использовать
/root/<root>
{
let $values := (value5, value6, value7)
return (
* except $values,
if ($values) then <countries>{ $values }</countries> else ()
)
}
</root>
https://xqueryfiddle.liberty -development.net / gWcDMeh / 7