Выберите диапазон элементов в XQuery 3.0

У меня есть следующая структура данных xml

<journey>
<leg origin='a' dest='b' />
<leg origin='b' dest='c' />
<leg origin='c' dest='d' />
<leg origin='d' dest='e' />
<leg origin='e' dest='f' />
... and so on
</journey>

Я хочу выбрать leg элементов от origin='b' до dest='e'

Я пытался использовать переворачивающееся окно, следующее за родным братом, но, похоже, он соответствует только первому и последнему элементам, между которыми ничего нет.

Я использую XQuery 3.0 в BaseX 8.6.


person swshaun    schedule 01.03.2018    source источник
comment
Пожалуйста, добавьте запрос, который показывает, что вы пробовали до сих пор. Кроме того, опишите, что именно означает «от источника до пункта назначения». Название вашего вопроса, кажется, указывает на то, что вы ищете минимальное и максимальное значения, тогда как пример может указывать на то, что вы пытаетесь найти пути.   -  person Christian Grün    schedule 01.03.2018


Ответы (1)


Поскольку не все условия охвата были даны в исходном вопросе, я предлагаю несколько ответов. Все они основаны на одном и том же прологе запроса и следующих предположениях (и, возможно, некоторых других):

  • искомый пункт отправления и пункт назначения существуют
  • все пункты отправления и назначения встречаются только один раз
  • нет циклов (например, bcb)

Пролог запроса

declare variable $JOURNEY :=
  <journey>
    <leg origin='a' dest='b' />
    <leg origin='b' dest='c' />
    <leg origin='c' dest='d' />
    <leg origin='d' dest='e' />
    <leg origin='e' dest='f' />
  </journey>;
declare variable $ORIGIN := 'b';
declare variable $DEST := 'e';

Использование переворачивающегося окна

Предположение: пункт назначения находится после источника.

for tumbling window $legs in $JOURNEY/leg
    start $s when $s/@origin = $ORIGIN
    end   $e when $e/@dest   = $DEST
return $legs

Использование следующего брата

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

let $origin := $JOURNEY/leg[@origin = $ORIGIN]
let $dest := $JOURNEY/leg[@dest = $DEST]
return (
  $origin,
  $origin/following-sibling::leg[. << $dest],
  $dest
)

Использование сравнений узлов

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

let $origin := $JOURNEY/leg[@origin = $ORIGIN]
let $dest := $JOURNEY/leg[@dest = $DEST]
return $JOURNEY/leg[
  . is $origin or
  . >> $origin and . << $dest or
  . is $dest
]

Рекурсивный подход

Предположение: Заказ не гарантируется.

declare function local:trace(
  $leg      as element(leg),
  $journey  as element(journey),
  $end      as xs:string
) as element(leg)* {
  $leg,
  for $dest in $leg/@dest[. != $end]
  return local:trace($journey/leg[@origin = $dest], $journey, $end)
};
local:trace($JOURNEY/leg[@origin = $ORIGIN], $JOURNEY, $DEST)
person Christian Grün    schedule 01.03.2018