删除空属性xquery3.0

时间:2014-09-14 17:45:25

标签: xml exist-db xquery-3.0

这是我的xml示例。

 let $test :=   
    <root>
        <a z="">stuff</a>
        <b z="12" y="">more stuff</b>
        <c>stuff</c>
        <d z = " " y="0" x ="lkj">stuff goes wild</d>
    </root>

我想使用查询删除空属性来获取此信息:

<root>
    <a>stuff</a>
    <b z="12">more stuff</b>
    <c>stuff</c>
    <d y="0" x ="lkj">stuff goes wild</d>
</root>  

我已经用我的查询得到了这么多,但是我不能让它只删除空属性,而不是删除所有属性,如果元素中有任何空属性。

declare function local:sanitize ($nodes as node()*) {
for $n in $nodes 
return typeswitch($n)
    case element() return 
        if ($n/@*[normalize-space()='']) then  (element{node-name($n)} {($n/@*[.!=''], local:sanitize($n/node()))})
        else (element {node-name($n)} {($n/@*, local:sanitize($n/node()))})
default return ($n)
};

该功能需要高效,因此我希望使用typeswitch。我觉得我很接近,但最后一步似乎让我望而却步。即。 z =&#34; &#34;没有被抓住。谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

代码的问题在于,在重新创建元素时,您需要检查完全空的属性,而不是在空白规范化后检查空属性。加上这个,你就没事了。

if ($n/@*[normalize-space()='']) then  (element{node-name($n)} {($n/@*[normalize-space(.)!=''], local:sanitize($n/node()))})

我简化了模式并区分了属性,元素和其他所有内容。过滤空属性,重新创建元素并返回其他任何内容。生成的函数更容易阅读和理解,并产生正确的输出:

declare function local:sanitize ($nodes as node()*) {
for $node in $nodes 
return typeswitch($node)
  (: filter empty attributes :)
  case attribute() return $node[normalize-space(.)]
  (: recreate elements :)
  case element() return 
    element { node-name($node) } {
      (: Sanitize all children :)
      for $child in $node/(attribute(), node())
      return local:sanitize($child)
    }
  (: neither element nor attribute :)
  default return $node
};