如何将节点从不同的命名空间复制到新文档?

时间:2015-02-23 21:00:54

标签: xquery marklogic

我在MarkLogic中有一个带有命名空间1的XML文档。现在我想从中复制一个节点并将其粘贴到另一个位于命名空间2中的文档中。

我编写了一个函数来从文档中获取这段数据(节点)。该函数返回文档2中位于命名空间1中的节点。

我希望此节点也与根文档位于同一名称空间中。

我可以从名称空间中删除节点吗?然后将其插入另一个文档? 获得所需结果的任何其他程序?

这里是我的结果,请注意根名称空间与类别元素名称空间不同...

<wijk id="1027K01" xmlns="http://www.nvsp.nl/wijk">
  <meta-data>
    <!--Generated by DIKW for NetwerkVSP STT!P -->
    <version>0.4</version>
    <dateCreated>2015-02-22+01:00</dateCreated>
  </meta-data>
  <category name="Geografie" xmlns="http://www.cendris.nl/postcode">
    <variable name="Postcode">
      <segment name="6 positie postcode">1027AA</segment>
      <segment name="5 positie postcode">1027A</segment>
      <segment name="4 positie postcode">1027</segment>
    </variable>
    <variable name="Gemeente">
      <segment name="Gemeentecode">363</segment>
      <segment name="Gemeentenaam">Amsterdam</segment>
    </variable>
    <variable name="Plaats">
      <segment name="Plaatsnaam">AMSTERDAM</segment>
    </variable>
    <variable name="Provincie">
      <segment name="Provinciecode">27</segment>
      <segment name="Provincienaam">Noord-Holland</segment>
    </variable>
    <variable name="Cebuco">
      <segment name="Cebuco naam">(21) Amsterdam-Purmerend</segment>
      <segment name="Cebuco code">21</segment>
    </variable>
    <variable name="Bible Belt">
      <segment name="nauwelijks">100</segment>
      <segment name="enigszins">0</segment>
      <segment name="redelijk sterk">0</segment>
      <segment name="sterk">0</segment>
      <segment name="zeer sterk">0</segment>
    </variable>
    <variable name="Urbanisatiegraad">
      <segment name="Zeer sterk stedelijk">100</segment>
      <segment name="Sterk stedelijk">0</segment>
      <segment name="Matig stedelijk">0</segment>
      <segment name="Weinig stedelijk">0</segment>
      <segment name="Niet stedelijk">0</segment>
    </variable>
  </category>
</wijk>

3 个答案:

答案 0 :(得分:2)

有一种简单的方法:使用functx:change-element-ns-deep功能。 functx库随MarkLogic一起发布。导入它们,用“”作为新命名空间调用该函数,然后关闭。

答案 1 :(得分:0)

您可以通过递归重构节点来剥离节点中的命名空间,并且它的子节点仅使用本地名称。您可以使用类似的方法将节点从一个名称空间移动到另一个名称空间。

注意:从节点中剥离命名空间会将该节点放入“空”命名空间。该节点将保留在“空”命名空间中,即使它被放置为不同命名空间节点的子节点。

以下是XQuery中的一些示例命名空间操作:

xquery version "1.0-ml";

declare namespace html = "http://www.w3.org/1999/xhtml";
declare namespace other = "other";

declare function local:remove-namespace($x as node()) as node()?
{
  if ($x instance of element())
  then
    element { fn:local-name($x) }  {
      $x/(@*,node()) ! local:remove-namespace(.)
    }
  else $x
};

declare function local:set-namespace($x as node(), $prefix as xs:string) as node()?
{
  if ($x instance of element())
  then
    element { xs:QName($prefix || ":" || fn:local-name($x)) }  {
      $x/(@*,node()) ! local:set-namespace(., $prefix)
    }
  else $x
};

let $x := <html:p>blah, blah <html:strong>__</html:strong> blah</html:p>
return (
  $x,
  local:remove-namespace($x),
  local:set-namespace($x, "other")
)

评估该样本的结果如下:

<html:p xmlns:html="http://www.w3.org/1999/xhtml">blah, blah <html:strong>__</html:strong> blah</html:p>,
<p>blah, blah <strong>__</strong> blah</p>,
<other:p xmlns:other="other">blah, blah <other:strong>__</other:strong> blah</other:p>

答案 2 :(得分:0)

命名空间节点在XQuery数据模型中并不是真正的一等公民。 XQuery工作组显然不认为我们应该被允许操纵它们。但是有一些技巧可用。

这是一个用8.0-1.1测试的例子:

declare function local:do(
  $n as node(), $ns as xs:string)
as node()
{
  typeswitch($n)
  case document-node() return document { local:do($n/node(), $ns) }
  case element() return element { QName($ns, local-name($n)) } {
    $ns,
    $n/@*,
    local:do($n/node(), $ns) }
  default return $n
};

<test xmlns="a">
  <fubar><baz/></fubar>
</test>
! local:do(., "b")

一旦您的XML元素具有所需的命名空间,您就可以照常操作它们:例如xdmp:node-insert-child,或者用于内存更新的其中一个库:https://github.com/ryanjdew/XQuery-XML-Memory-Operations等。

另一个有用的命名空间技巧涉及XPath namespace轴。如果您有嘈杂的名称空间声明,这也会有所帮助。

<test xmlns="a">
  <b:fubar xmlns:b="b"><baz/></b:fubar>
  <b:fubar xmlns:b="b"><buz/></b:fubar>
</test>
! element { node-name(.) } {
  node()/namespace::*,
  @*,
  node() }

这具有将xmlns:b声明提升到根元素级别的效果。

最后,您有时可以使用xdmp:quotexdmp:unquote进行操作,它具有默认的命名空间选项。