使用XQuery递归获取某个节点的祖先

时间:2010-08-22 11:20:33

标签: xml recursion xquery

我有XML例如:

<types>
  <type type="A">
    <type type="A.A"/>
    <type type="A.B">
      <type type="A.B.A"/>
    </type>
    <type type="A.C"/>
  </type>
</types>

现在,我输入的字符串如下:“A.B.A”。我希望得到所有具有此字符串的祖先和自身节点,如“type”属性的值。这意味着:

<types>
  <type type="A"/>
  <type type="A.B"/>
  <type type="A.B.A"/>
</types>

(当然这里的类型名称只是示例而不是那么简单,所以我不能使用子字符串函数)
我有两个XML Schema:TypesTree.xsd和Ancestros.xsd 两者都有元素“类型”和“类型”。

所以也许,我可以使用带有祖先轴的XPath,其中$ types包含类型树:

let $seq := $types//type[@type=$typeName]/ancestor::*
$seq := ($seq, $types//type[@type=$typeName])

我是XQuery的新手,我不确定这会起作用,但是没关系,重要的是我没有在我的XQuery处理器(!)中实现“祖先”轴,我需要为此处理器显式编写代码。

所以我想写一些递归函数。 设“tre:”是TypesTree.xsd的前缀和Ancestors.xsd的“anc:”。 该函数将获得tre:type元素并返回anc:type元素的序列。

declare function BuildAncestors($type as element(tre:type), $typeName as xs:string) as element(anc:type)*
{
  for $currentType in $type/tre:type (: for each nested type node :)
  return
  if ($currentType[@type=$typeName]) (: if current type node's attribute's values is what we search for :)
  then ($currentType) (: return this node :)
  else (: if this node's attribute's value isn't what we search, check it's children :)
    let $retSeq := BuildAncestors($currentType, $typeName) (: get sequence of all ancestor's of this type till this node or null if $currentType has not searched node in it's descendants :)
    if ($retSeq) (: if not null returned :)
    then ($currentType, $retSeq) (: return new sequence built from this node and returned sequence :)
    else () (: return null :)
}

所以,很明显它不起作用。我甚至不知道如何返回序列,添加序列,返回null,检查是否返回null ...

任何人都知道我如何得到所有的祖先?

谢谢你。

2 个答案:

答案 0 :(得分:1)

使用

//type[@type=$pType]//ancestor-or-self::type[starts-with($pType, @type)]

如果您的XQuery处理器符合W3C规范,它可能会实现ancestor:: and the ancestor-or-self::轴。

您得到的错误很可能是由于拼写错误 - 轴名称为ancestor,而不是ancestors

答案 1 :(得分:0)

正确的轴名称为ancestor,而不是ancestors。此外,使用轴ancestor-or-self会更简单。