问题描述
我正在尝试使用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>
我已将item值和ID值作为参数传递,而不是在XPath中对其进行硬编码。根据在何处以及如何链接这些东西,您也许可以对所有行进行一次更新,从而从另一个表中获取项目/ ID映射。
这在Oracle e.g. 18c的更高版本中有效,我认为应该从11.2.0.3开始工作。不过,它在早期版本中将无法使用,因此,如果您的确是10g,则需要使用其他方法。