Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 删除空属性xquery3.0_Xml_Exist Db_Xquery 3.0 - Fatal编程技术网

Xml 删除空属性xquery3.0

Xml 删除空属性xquery3.0,xml,exist-db,xquery-3.0,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>

下面是我的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>

该功能需要执行,因此我希望使用typeswitch。我觉得我很接近,但最后一步似乎离我很遥远。ie.z=”“不会被抓到。谢谢你的帮助

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

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
};

谢谢,我不想在第一个case语句中检查属性。这实际上会影响节点的处理顺序吗?不会,因为它会在所有节点上循环并逐个处理。要知道的唯一重要的一点是,属性总是必须首先创建,因此
$node/(attribute(),node()
部分也必须这样做(反过来做会产生错误消息)。
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
};