Oracle Sql赋予名称空间属性

问题描述

我正在尝试使用Oracle sql语句将属性添加到xml。 XML作为数据存储在表“ item”的列中。我在添加新的'id'属性,值如以下查询中给出的'123'时没有问题。

UPDATE item SET item_xml = INSERTCHILDXML(item_xml,'/item','@id','123') where customer_id = '1';

但是,如果我要添加xml名称空间,而不是常规的'id'属性,如果我想在xml下面附加诸如'xml:id'之类的名称空间,则会引发错误无效的XPATH表达式”,请告诉我有什么方法可以避免引发此错误

UPDATE item SET item_xml = INSERTCHILDXML(item_xml,'@xml:id','123') where customer_id = '1';

我了解我们在通常情况下不使用名称空间,但是我以'id'属性为例,因为我们的应用程序会生成xml,而该XML在其他需要属性属性的其他系统中却很少使用。

更新xml后,外观应类似于以下内容,请假定属性'xml:id =“ 123”'最初不存在于表'item'的xml克隆中。

<items>
  <item xml:id="123">Apple</item>
<items>

解决方法

我认为这不受支持。

您可以使用modify XPath来完成;副作用是名称空间声明会出现在属性中,即使它已经在文档中声明过;希望与您的下游系统无关:

UPDATE item SET item_xml = XMLQuery('
  copy $n := .
  modify (  
    for $i in $n/items/item[$item][not(@xml:id)]
      return insert node attribute xml:id {$id} into $i
    )
  return $n'
  passing item_xml,'Apple' as "item",123 as "id"
  returning content
)
where customer_id = 1;
ITEM_XML
----------------------------------------------------------------------------------
<items>
  <item xml:id="123" xmlns:xml="http://www.w3.org/XML/1998/namespace">Apple</item>
</items>

db<>fiddle

我已将item值和ID值作为参数传递,而不是在XPath中对其进行硬编码。根据在何处以及如何链接这些东西,您也许可以对所有行进行一次更新,从而从另一个表中获取项目/ ID映射。

这在Oracle e.g. 18c的更高版本中有效,我认为应该从11.2.0.3开始工作。不过,它在早期版本中将无法使用,因此,如果您的确是10g,则需要使用其他方法。