Как использовать пространство имен Dynami c с переключателем типов? - PullRequest
2 голосов
/ 02 апреля 2020
declare function local:change($node) 
{ 
  typeswitch($node) 
    case element(add) return 
      local:do-something()

    default return $node 
};
let $test1 := <test xmlns="http:example.com/A">
                <add>x1</add>
                <b>x</b>
             </test>

let $test2 := <test xmlns="http:example.com/B">
                <add>x1</add>
                <b>x</b>
             </test>

В переключателе типов при добавлении элемента выполняется дальнейшая обработка. Код является общим c. Документы, которые будут отправлены для обработки, будут иметь те же элементы, но пространство имен может отличаться, как в примере.

Как динамически предоставлять пространство имен в элементе case.

Ответы [ 2 ]

3 голосов
/ 02 апреля 2020

Если вы объявите

declare namespace A = "http:example.com/A";
declare namespace B= "http:example.com/B";

, вы сможете использовать

case element(A:add) | element(B:add)

хотя бы в стандартном XQuery (https://www.w3.org/TR/xquery-31/#prod -xquery31-SequenceTypeUnion ) , Я не знаю, поддерживает ли это Marklogi c.

Я не думаю, что типы последовательностей допускают подстановочный знак пространства имен в форме, например, element(*:add), поэтому я не уверен, что предложить для вашего большое количество пространств имен, проверьте, нужен ли вам переключатель типов и сопоставление типов последовательностей, или вы не можете просто выбрать *:add в шаге выражения пути или предиката, например, if ($node[self::*:add]), например, вместо

typeswitch($node) 
    case element(add) return 
      local:do-something()
    ...

вы можете использовать

if ($node[self::*:add])
then local:do-something()
else $node 
1 голос
/ 04 апреля 2020

Один из способов обрабатывать элементы из разных пространств имен одинаково (как один и тот же «вид» элемента), помещать их в одно и то же пространство имен или в пространство имен. В зависимости от того, что делает local:do-something(), проверенная по типу копия может захотеть быть пустой или содержать оригинальное содержимое (как показано) или содержать аналогично очищенные от имен пространства потомки.

declare function local:normalize-namespace($element){
    element { local-name($element) }  { $element/@*, $element/node() }
};

declare function local:change($node) 
{
  typeswitch(local:normalize-namespace($node)) 
    case element(add) return 
      local:do-something()

    default return $node 
};
...