0

我有一个结构如下的文档:

<INVT_DATA xmlns="http://www.mrbook.com/InventoryData">
    <AUTHOR>...</AUTHOR>
    <TITLE>...</TITLE>
    <PUBLISHER>...</PUBLISHER>
</INVT_DATA>

INVT_DATA 的子子元素始终是元素,而不是文本节点。我想使用 XQuery 来比较具有相同结构的新文档。如果新元素和原始元素中都存在子元素,则应将其替换。如果新元素中存在子元素,但旧元素中不存在,则应将其附加到 INVT_DATA。

我认为这个 XQuery 会起作用,但它似乎总是只是附加节点:

declare namespace invtdata="http://www.mrbook.com/InventoryData";

copy $oldInvtData := $oldXml

modify 
( 
  for $mpf in $newXml/invtdata:INVT_DATA/*
  let $oldMpf := $oldInvtData/invtdata:INVT_DATA/*[name()=name($mpf)] 
  return if(exists($oldMpf)) then 
  replace node $oldMpf with $mpf 
  else insert node $mpf into $oldInvtData 
)
return $oldInvtData 

我搜索了其他类似的问题并找到了这个,但这对于我想做的事情来说有点过分了。有什么建议么?如果有帮助,我将使用 Oracle XML DB 版本 11.2.0.3 中的 XmlQuery。

4

2 回答 2

1

匹配 name() 容易出错,因为 name() 返回 XML 中出现的名称——如果您的两个输入将不同的前缀绑定到命名空间名称,则检查 name() 的相等性将不会成功。如果您将谓词更改为

[local-name() = local-name($mpf) 
 and
 namespace-uri() = namespace-uri($mpf)]

你的代码应该工作得更好。


附录:

也就是说,给定一个包含以下内容的 XML 文档 Brad1.xml:

<INVT_DATA xmlns="http://www.mrbook.com/InventoryData">
  <AUTHOR>old author</AUTHOR>
  <TITLE>old title</TITLE>
  <PUBLISHER>old publisher</PUBLISHER>
</INVT_DATA>

和一个包含以下内容的 XML 文档 Brad2.xml:

<id:INVT_DATA xmlns:id="http://www.mrbook.com/InventoryData">
  <id:AUTHOR>new author</id:AUTHOR>
  <id:PUBLISHER>new publisher</id:PUBLISHER>
</id:INVT_DATA>

编码:

declare namespace invtdata="http://www.mrbook.com/InventoryData";

declare variable $oldXml := doc('.../Brad1.xml');
declare variable $newXml := doc('.../Brad2.xml');

copy $oldInvtData := $oldXml

modify 
( 
  for $mpf in $newXml/invtdata:INVT_DATA/*
  let $oldMpf := $oldInvtData/invtdata:INVT_DATA/*
                 [local-name() = local-name($mpf)
                  and namespace-uri() = namespace-uri($mpf)] 
  return if(exists($oldMpf)) then 
  replace node $oldMpf with $mpf 
  else insert node $mpf into $oldInvtData 
)
return $oldInvtData 

评估为:

<INVT_DATA xmlns="http://www.mrbook.com/InventoryData"
           xmlns:id="http://www.mrbook.com/InventoryData">
    <id:AUTHOR>new author</id:AUTHOR>
    <TITLE>old title</TITLE>
    <id:PUBLISHER>new publisher</id:PUBLISHER>
</INVT_DATA>

如果您根本没有看到任何节点被替换,一个可能的原因是 XPath 表达式中的错误(您确定它们都正确吗?没有拼写错误?);另一个是未能按您的意愿绑定 $oldXml 或 $newXml。

于 2013-08-25T22:02:04.430 回答
0

事实证明这是正确的代码......只是一个小调整。

declare namespace invtdata="http://www.mrbook.com/InventoryData";

declare variable $oldXml := doc('.../Brad1.xml');
declare variable $newXml := doc('.../Brad2.xml');

copy $oldInvtData := $oldXml

modify 
( 
  for $mpf in $newXml/invtdata:INVT_DATA/*
  let $oldMpf := $oldInvtData/invtdata:INVT_DATA/*
                 [local-name() = local-name($mpf)
                  and namespace-uri() = namespace-uri($mpf)] 
  return if(exists($oldMpf)) then 
  replace node $oldMpf with $mpf 
  else insert node $mpf into $oldInvtData/invtdata:INVT_DATA 
)
return $oldInvtData 

谢谢您的帮助!

于 2013-09-05T15:03:12.710 回答