Строки токенов XQuery с одним и несколькими значениями

У меня есть следующий файл XML:

<layout>
 <layout-structure>
  <layout-root id="layout-root">
    <layout-chunk id="header-text">
         <layout-leaf xref="lay-1.01"/>
         <layout-leaf xref="lay-1.02"/>
    </layout-chunk>
    <layout-leaf xref="lay-1.03"/>
  </layout-root>
  <layout-root id="layout-root-two">
    <layout-chunk id="header-text-two">
     <layout-leaf xref="lay-1.04"/>
     <layout-leaf xref="lay-1.05"/>
     <layout-leaf xref="lay-1.06"/>
    </layout-chunk>
  <layout-leaf xref="lay-1.07"/>
 </layout-root>
</layout-structure>

<realization>
  <text xref="lay-1.01 lay-1.04"/>
  <text xref="lay-1.02 lay-1.05"/>
  <graphics xref="lay-1.03 lay-1.06" type="1"/>
  <graphics xref="lay-1.07" type="2"/>
</realization>
</layout>

Я хочу извлечь значения атрибута xref элемента graphics, чтобы ограничить вывод в предложении for показанной функции ниже.

declare function local:gfx($root, $graphics) {
let $graphic-xrefs := tokenize($graphics/@xref, " ")
for $layout-leafs in $root//layout-leaf[@xref = $graphic-xrefs]
return concat('"', $layout-leafs/@xref, '" ', $dotgraphics, ';', $newline) 
};

Однако это вызывает ошибку, поскольку некоторые атрибуты xref в элементе graphics содержат одно значение, как в случае <graphics xref="lay-1.07"/>.

Можно ли использовать tokenize для получения значений graphics/xref или мне следует использовать другой подход?


person ritzdiamond    schedule 04.09.2012    source источник


Ответы (2)


Вы можете попробовать изменить способ создания $graphic-xrefs...

declare function local:gfx($root, $graphics) {
    let $graphic-xrefs := 
        for $xref in $graphics/@xref
        return
            tokenize($xref,' ')
    for $layout-leafs in $root//layout-leaf[@xref = $graphic-xrefs]
    return concat('"', $layout-leafs/@xref, '" ', $dotgraphics, ';', $newline) 
};
person Daniel Haley    schedule 06.09.2012

Это не должно вызывать проблем, так как tokenize просто вернет всю строку, если разделенная строка не находится в строке поиска.

Для работы с такими обычно может быть полезен обычный оператор if (...) then ... else .... Кроме того, вы можете использовать конструкцию try { ... } catch {...} для обработки непредвиденных ситуаций.

Ваш код действительно работает так, как ожидалось, когда я запускаю это:

declare variable $t :=
<layout>
 <layout-structure>
  <layout-root id="layout-root">
    <layout-chunk id="header-text">
         <layout-leaf xref="lay-1.01"/>
         <layout-leaf xref="lay-1.02"/>
    </layout-chunk>
    <layout-leaf xref="lay-1.03"/>
  </layout-root>
  <layout-root id="layout-root-two">
    <layout-chunk id="header-text-two">
     <layout-leaf xref="lay-1.04"/>
     <layout-leaf xref="lay-1.05"/>
     <layout-leaf xref="lay-1.06"/>
    </layout-chunk>
  <layout-leaf xref="lay-1.07"/>
 </layout-root>
</layout-structure>

<realization>
  <text xref="lay-1.01 lay-1.04"/>
  <text xref="lay-1.02 lay-1.05"/>
  <graphics xref="lay-1.03 lay-1.06" type="1"/>
  <graphics xref="lay-1.07" type="2"/>
</realization>
</layout>;

declare function local:gfx($root, $graphics) {
let $graphic-xrefs := tokenize($graphics/@xref, " ")
for $layout-leafs in $root//layout-leaf[@xref = $graphic-xrefs]
return $layout-leafs/@xref
};

local:gfx($t, $t/realization/graphics[2])

Обратите внимание, что последний <layout> в вашем фрагменте кода должен быть закрывающим оператором.

person dirkk    schedule 04.09.2012
comment
Спасибо за ваш вклад @dirkk! Любопытно, что я получаю следующее сообщение об ошибке в Editix: A sequence of more than one item is not allowed as the first argument of tokenize() ("lay-1.03", "lay-1.06") - person ritzdiamond; 04.09.2012
comment
Это произошло, когда вы на самом деле выполнили мой код (или только для вашего исходного кода)? Потому что для моего кода я был бы весьма удивлен. Сообщение об ошибке также предполагает, что действительно ошибка заключается в том, как вы вызываете функцию local:gfx: похоже, что $graphics/@xref — это не просто один элемент, а последовательность нескольких узлов. Но в качестве входных данных для токенизации вы должны передать строку xs: без последовательности. Я настоятельно рекомендую проверить, как вы вызываете функцию и какие переменные вы передаете. Если вы хотите получить дополнительные рекомендации, пожалуйста, напишите, как именно вы вызываете функцию. - person dirkk; 04.09.2012