使用xquery使用except()返回整个元素

时间:2014-08-30 08:33:31

标签: xquery except

目前我正在做一些xquery,如下所示。

XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<animal>
    <dog name="ada">
        <color>black</color>
        <byear>2012</byear>
    </dog>
    <dog name="bob">
        <color>black</color>
        <byear>2011</byear>
    </dog>
    <cat name="cathy">
        <color>black</color>
        <byear>2010</byear>
    </cat>
    <cat name="dione">
        <color>brown</color>
        <byear>2009</byear>
    </cat>
</animal>

预期产出:

<?xml version="1.0" encoding="UTF-8"?>
<animal>
    <color>black</color>
    <dog name="ada">
        <byear>2012</byear>
    </dog>
    <dog name="bob">
        <byear>2011</byear>
    </dog>
    <cat name="cathy">
        <byear>2010</byear>
    </cat>
</animal>

我的代码如下:

<animal>
{ for $a in distinct-values(//animal/*/color)
    return <color>{$a}</color>
    { for $b in //animal/*[color=$a]
    where $b//color="black"
        return $b/* except $b/color
</animal>

并且输出很好,但它不包含父标记(例如<dog name="ada"> </dog>)。

此外,我还尝试了类似return $b except $b/color的内容,这次输出包含了父标记,但它也包含了&#34;颜色&#34;在儿童标签上。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

在普通的XQuery中,您不能只返回节点的一部分。您要么返回整个节点及其所有子节点,要么选择一些子节点或后代并完全返回这些节点。

您可以做的是创建一个与element {node-name(...)} {...}旧节点同名的新节点,然后将您想要的子节点从旧节点复制到新节点。

类似的东西:

<animal>
{ for $a in distinct-values(//animal/*/color)
    return (
      <color>{$a}</color>,
      for $b in //animal/*[color=$a]
      return element {node-name($b)} {$b / @*,  $b/node() except $b/color }
    )
}
</animal>

(使用XQuery Update扩展,您还可以删除不需要的节点而不是复制它们)