使用XQuery重命名名称空间前缀(更新)

时间:2013-07-19 17:17:56

标签: xml xquery xml-namespaces

使用文本处理工具和语言可以很容易地解决以下问题,但这不是我应该如何做的...

使用XQuery(Update)在大型XML文档中重命名名称空间前缀的最简洁,最便宜的方法是什么?

来源:

<a:root xmlns:a="http://my.old.url/"/>
  <a:sub/>
</a:root>

我想得到的结果:

<b:root xmlns:b="http://my.old.url/"/>
  <b:sub/>
</b:root>

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

XQuery更新

在XQuery Update中,您可以使用rename表达式重命名给定命名空间中的所有元素:

declare namespace ns='http://my.old.url/';
for $nd in doc('your-db')//ns:*
return rename node $nd as QName('http://my.old.url/', concat('b:', local-name($nd)))

如果您不希望更改是永久性的,您也可以将更新包装在Transform Expression中:

declare namespace ns='http://my.old.url/';
copy $doc :=
  document{
    <a:root xmlns:a="http://my.old.url/">
      <a:sub/>
    </a:root>
  }
modify
  for $nd in $doc//ns:*
  return rename node $nd as QName('http://my.old.url/', concat('b:', local-name($nd)))
return $doc

答案 1 :(得分:0)

这在XSLT中可能更容易做,但在XQuery中我认为你基本上会做同样的事情。声明所需的名称空间前缀,然后递归处理节点并更新元素名称以使用该前缀。

xquery version "1.0";
declare namespace b="http://my.old.url/";

declare function local:update-ns-prefix($node)
{
  typeswitch($node)    
    case element() return 
      element { xs:QName(concat('b:',local-name($node))) }
      {
        $node/@*, 
        for $n in $node/node()
        return local:update-ns-prefix($n)
      }
    default return $node
};

let $xml :=
<a:root xmlns:a="http://my.old.url/">
  <a:sub xmlns:a="http://my.old.url/"/>
</a:root>
return local:update-ns-prefix($xml)