Xquery 如何将动态命名空间与类型开关一起使用? 声明函数本地:更改($node) { 类型开关($node) 案例元素(添加)返回 当地人:做点什么 默认返回$node }; 让$test1:= x1 x 让$test2:= x1 x

Xquery 如何将动态命名空间与类型开关一起使用? 声明函数本地:更改($node) { 类型开关($node) 案例元素(添加)返回 当地人:做点什么 默认返回$node }; 让$test1:= x1 x 让$test2:= x1 x,xquery,marklogic,Xquery,Marklogic,在typeswitch中添加元素时,执行一些进一步的处理。代码是通用的。将被发送以进行处理的文档将具有相同的元素,但名称空间可以与示例中的名称空间不同 如何在case元素中动态提供名称空间。如果您声明 declare function local:change($node) { typeswitch($node) case element(add) return local:do-something() default return $node };

在typeswitch中添加元素时,执行一些进一步的处理。代码是通用的。将被发送以进行处理的文档将具有相同的元素,但名称空间可以与示例中的名称空间不同

如何在case元素中动态提供名称空间。

如果您声明

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>
你应该能够使用

declare namespace A = "http:example.com/A";
declare namespace B= "http:example.com/B";
至少在标准XQuery()中,我不知道Marklogic是否支持它

我认为序列类型不允许名称空间通配符的形式,例如
元素(*:add)
,因此我不确定为大量名称空间建议什么,检查是否需要类型开关和序列类型匹配,或者是否不能在路径表达式或谓词的步骤中简单地选择
*:add
,例如
if($node[self:*:add])
,例如,而不是

case element(A:add) | element(B:add)
你可以用

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

以相同的方式(作为相同的“种类”元素)处理来自不同名称空间的元素的一种方法是将它们放入相同的名称空间,或者不放入任何名称空间。根据
local:do-something()
所做的工作,选中类型的副本可能希望为空,或者包含原始内容(如图所示),或者包含类似的子项

if ($node[self::*:add])
then local:do-something()
else $node 

谢谢你,马丁。这肯定会奏效的。但我的要求有点不同。我没有两个名称空间不同的文档。这个数字可以更多。我正在寻找一些通用的方法来做到这一点。如果我必须使用100个不同的名称空间处理100万个文档,那么我需要合并100个元素。因此,寻找一种不进行100次联合的方法来解决它。@KishanAshra,我不确定是否有一种处理类型切换和序列类型的方法,也许路径
*:add
或谓词
[self::*:add]
会有帮助。MarkLogic支持SequenceTypeUnion,但标准只允许
元素(*)
具有可选类型。听起来像是
self::*:xx
是你最好的选择@martin和@grtjn解决方案
self::*:add
不起作用。正如正确地说的,元素测试只允许元素(*)。@KishanAshra,我在回答中详细说明了我建议的表达式应该如何使用,它不能与
typeswitch
一起使用,而是与
if-then-else
一起使用。
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 
};