【问题标题】:Get ancestors of some node with XQuery recursion使用 XQuery 递归获取某个节点的祖先
【发布时间】:2010-08-22 11:20:33
【问题描述】:

例如,我有 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 模式: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...

有谁知道我怎样才能得到所有的祖先?

谢谢你的到来。

【问题讨论】:

    标签: xml recursion xquery


    【解决方案1】:

    使用

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

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

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

    【讨论】:

    • 对不起,我的真实代码有祖先:: 而不是祖先::。只是我们的开发网络无法访问inetrnet,所以我可能不会复制代码。但是我找到了解决方案,我会发布它。无论如何谢谢你。
    【解决方案2】:

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

    【讨论】:

    • 对不起,我的真实代码有祖先:: 而不是祖先::。只是我们的开发网络无法访问inetrnet,所以我可能不会复制代码。但是我找到了解决方案,我会发布它。无论如何谢谢你。
    猜你喜欢
    • 2020-01-09
    • 1970-01-01
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多