XQuery:调试递归函数

XQuery:调试递归函数,xquery,Xquery,xqy文件: import module namespace functx="http://www.functx.com"; declare variable $defaultXMLNS:="http://www.test.com#"; declare variable $defaultXMLBase:=$defaultXMLNS; declare function local:descriptionConstructorTail( $seq as item()*, $i as x

xqy文件:

import module namespace functx="http://www.functx.com";

declare variable $defaultXMLNS:="http://www.test.com#";
declare variable $defaultXMLBase:=$defaultXMLNS;

declare function local:descriptionConstructorTail(
  $seq as item()*, 
  $i as xs:integer?, 
  $res as item()*
)
{
  if($i <= 0)
  then $res
  else local:descriptionConstructorTail($seq, 
           $i - 1, 
           functx:value-union($res, 
                  (<test1 about="{$seq[$i]/@value}"/>)))
};

declare function local:descriptionConstructor($pnode as node()*)
{
  local:descriptionConstructorTail($pnode//xs:enumeration, 
        count($pnode//xs:enumeration), 
        ())
};

element test
{
  local:descriptionConstructor(doc("./test2.xsd"))
}
导入模块命名空间functx=”http://www.functx.com";
声明变量$defaultXMLNS:=”http://www.test.com#";
声明变量$defaultXMLBase:=$defaultXMLNS;
声明函数本地:descriptionConstructorTail(
$seq as item()*,
$i作为xs:integer?,
$res作为项目()*
)
{

如果($i)而
functx
库是一个非常方便的实用函数集合,那么了解这些函数的确切用途是否很重要,这样可以避免类似这样的意外情况。
functx:value union(…)
的实现如下:

declare function functx:value-union(
  $arg1 as xs:anyAtomicType*,
  $arg2 as xs:anyAtomicType*
) as xs:anyAtomicType* {
  distinct-values(($arg1, $arg2))
};
因此,它只将
不同的值(…)
应用于其输入的串联。由于此函数适用于
xs:anyAtomicType
类型的值,因此XML节点被原子化。这只留下它们的文本内容,而元素没有这些内容。因此,您只需反复构建空序列的并集

这应该很好:

declare function local:descriptionConstructorTail($seq as item()*, $i as xs:integer?, $res as item()*) {
  if($i <= 0) then $res
  else local:descriptionConstructorTail($seq, $i - 1, distinct-values(($res, $seq[$i]/@value)))
};

declare function local:descriptionConstructor($pnode as node()*) {
  let $enums := $pnode//xs:enumeration
  for $res in local:descriptionConstructorTail($enums, count($enums), ())
  return <test1 about="{$res}"/>
};

element test {
  local:descriptionConstructor(doc("./test2.xsd"))
}

您声明的名称空间与文档中定义的名称空间不同(
#
在文档末尾)。@JensErat实际上这并不影响输出
<test>
<test1 about="small"/>
<test1 about="medium"/>
<test1 about="large"/>
</test>
declare function functx:value-union(
  $arg1 as xs:anyAtomicType*,
  $arg2 as xs:anyAtomicType*
) as xs:anyAtomicType* {
  distinct-values(($arg1, $arg2))
};
declare function local:descriptionConstructorTail($seq as item()*, $i as xs:integer?, $res as item()*) {
  if($i <= 0) then $res
  else local:descriptionConstructorTail($seq, $i - 1, distinct-values(($res, $seq[$i]/@value)))
};

declare function local:descriptionConstructor($pnode as node()*) {
  let $enums := $pnode//xs:enumeration
  for $res in local:descriptionConstructorTail($enums, count($enums), ())
  return <test1 about="{$res}"/>
};

element test {
  local:descriptionConstructor(doc("./test2.xsd"))
}
declare function local:descriptionConstructor($pnode as node()*) {
  for $res in
    fold-right(
      $pnode//xs:enumeration,
      (),
      function($enum, $res) {
        distinct-values(($enum/@value, $res))
      }
    )
  return <test1 about="{$res}"/>
};

element test {
  local:descriptionConstructor(doc("./test2.xsd"))
}