我为一个具体的问题伤透了脑筋,在那里我什么也找不到。背景:我们将XML配置保存在Oracle数据库的CLOB中。但是,我们将系统切换到新系统。我需要改变所有的<long>
到<int>
后的属性“相对”。用于演示:这
<?xml version="1.0" encoding="utf-8"?><!-- SERIALIZER="XSTREAM" --><map>
<entry>
<string>CalendarMaintenance</string>
<map>
<entry>
<string>date</string>
<censored>
<dbiObjectKey>0</dbiObjectKey>
<dbiObjectState>C</dbiObjectState>
<persistentState>0</persistentState>
<id>date</id>
** <value>
<string>Relative</string>
<long>30</long>
<long>30</long>
</value>**
<sortCriteria>1</sortCriteria>
<notRequest>false</notRequest>
<nullRequired>false</nullRequired>
<satisfiableCondition>true</satisfiableCondition>
</censored>
</entry>
</map>
</entry>
</map>
需要改成这样
<?xml version="1.0" encoding="utf-8"?><!-- SERIALIZER="XSTREAM" --><map>
<entry>
<string>CalendarMaintenance</string>
<map>
<entry>
<string>date</string>
<censored>
<dbiObjectKey>0</dbiObjectKey>
<dbiObjectState>C</dbiObjectState>
<persistentState>0</persistentState>
<id>date</id>
** <value>
<string>Relative</string>
<int>30</int>
<int>30</int>
</value>**
<sortCriteria>1</sortCriteria>
<notRequest>false</notRequest>
<nullRequired>false</nullRequired>
<satisfiableCondition>true</satisfiableCondition>
</censored>
</entry>
</map>
</entry>
</map>
所以简而言之,在Relative Part后面的long标记需要改为int。问题是,它可能是一个标签或两个标签。
有人有什么主意吗?或者有人在Oracle中有Regexp_replace或XML函数的经验?
提前感谢!
我已经尝试了多种解决方案与更新声明。我尝试使用regexp_replace和XML函数,尽管我对这两种方法都不了解。
这只适用于两个长标签:
update table_name
set column_name = regexp_replace(column_name, '<value>(\s+)<string>Relative</string>(\s+)<long>([0-9a-zA-Z]+)</long>(\s+)<long>([0-9a-zA-Z]+)</long>', '<value>\1<string>Relative</string>\2<int>\3</int>\4<int>\5</int>')
where regexp_like(column_name, '<long>([0-9]+)</long>');
这个函数使用一个XML函数,但不返回整个输入XML(如上所示)
update table_name
set column_name = regexp_replace(
EXTRACT(XMLTYPE.createXML(column_name), '//value[string="Relative"]/long'),
'<long>([0-9a-zA-Z]+)</long>',
'<int>\1</int>')
where
regexp_like(column_name, '<long>([0-9]+)</long>');
输出是这样的:
<int>30</int><int>30</int>
1条答案
按热度按时间2vuwiymt1#
NEVER使用字符串函数解析XML;始终使用适当的XML解析器。
您可以使用FLOWR表达式重写XML:
其中,对于样本数据:
然后,表格将包含:
| XML|
| --|
| 日历维护日期0C0日期相对30301假假真|
如果你想替换任何
value
标签的子标签(而不是在特定路径上),那么用$e//value[string="Relative"]/long
替换XPATH$e/map/entry/map/entry/censored/value[string="Relative"]/long
。fiddle
如果你只想更新
string
元素之后的兄弟元素,那么你可以使用XPATH$e//value/string[text()="Relative"]/following-sibling::long
。fiddle