【问题标题】:Rename namespace prefixes with XQuery (Update)使用 XQuery 重命名命名空间前缀(更新)
【发布时间】:2013-07-19 17:17:56
【问题描述】:

使用文本处理工具和语言可以轻松解决以下问题,但我猜这不是应该的..

使用 XQuery(更新)重命名大型 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>

有什么想法吗?

【问题讨论】:

    标签: xml xquery xml-namespaces


    【解决方案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
    

    【讨论】:

    • 谢谢!有没有办法从结果中删除旧的“a”前缀声明?
    【解决方案2】:

    这在 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)
    

    【讨论】:

    • 谢谢!是否有任何可用的解决方案占用更少的内存?我注意到对于具有几兆或千兆字节的较大文档,递归方法失败了。接下来,您的查询假定您使用 MarkLogic 来处理您的查询。替换现有数据库文档中的命名空间前缀怎么样?
    • @HannesBauer 我忘了删除 ML 版本,但这应该适用于任何 XQuery 兼容的处理器。但是,我想不出一个使用更少内存的简单替代方案(functx 有一个 XQuery 函数,它做类似的事情,它也递归处理)。我唯一能想到的是一个批处理,它接受一些节点并以非递归方式更新它们。然后按顺序分拆各个事务中的作业。这假设文档在数据库中,并且您有一些更新节点的方法。
    • 我决定投票支持 Leo 的解决方案,因为它更接近我所寻找的。无论如何,谢谢!
    • @HannesBauer 如果您指定了您使用的数据库,我可以提供一个解决方案。并非所有 XQuery 数据库都支持 XQuery 更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多