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

使用xquery使用except()返回整个元素,xquery,except,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"> <

目前我正在做一些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>
输出良好,但不包括父标签,例如


此外,除了$b/color之外,我还尝试了类似return$b的东西,这次的输出包括父标记,但是它也包括子标记上的颜色。有什么想法吗?

在普通的XQuery中,您不能只返回节点的一部分。您可以返回整个节点及其所有子节点/子节点,也可以选择一些子节点/子节点并完全返回这些节点

相反,您可以创建一个新节点,该节点的名称与元素为{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更新扩展,您还可以删除不需要的节点,而不是复制它们