[英]How to delete a node from Oracle XMLTYPE based on a condition?
我有一个存储在CLOB
列中的 XML 数据,我想根据特定条件删除一些节点。
XML 数据示例:
<?xml version="1.0" encoding="UTF-8"?>
<payment>
<person>
<surname>Marco</surname>
<name>Gralike</name>
<salary>2345</salary>
</person>
<person>
<surname>ABC</surname>
<name>TEST</name>
<salary>1234</salary>
<person>
<surname>Tiger</surname>
<name>Scott</name>
<salary>2222</salary>
</person>
</person>
</payment>
<payment>
<person>
<surname>BertJan</surname>
<name>Meinders</name>
<salary>3456</salary>
<salary>125</salary>
</person>
<person>
<surname>XYZ</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
</payment>
<payment>
<person>
<surname>Chris</surname>
<name>Gralike</name>
<salary>4567</salary>
</person>
<person>
<surname>LMN</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
</payment>
如果包含 TEST,我需要一个 Oracle PLSQL 脚本来删除所有人员标签。
最终输出将是:
<?xml version="1.0" encoding="UTF-8"?>
<payment>
<person>
<surname>Marco</surname>
<name>Gralike</name>
<salary>2345</salary>
</person>
</payment>
<payment>
<person>
<surname>BertJan</surname>
<name>Meinders</name>
<salary>3456</salary>
<salary>125</salary>
</person>
</payment>
<payment>
<person>
<surname>Chris</surname>
<name>Gralike</name>
<salary>4567</salary>
</person>
</payment>
提前致谢。
您提供的XML没有根,因此XML解析器无法对其进行解析。
假设确实如此(例如payments
),如下所示:
create table t(txt clob);
insert into t values('<?xml version="1.0" encoding="UTF-8"?>
<payments>
<payment>
<person>
<surname>Marco</surname>
<name>Gralike</name>
<salary>2345</salary>
</person>
<person>
<surname>ABC</surname>
<name>TEST</name>
<salary>1234</salary>
<person>
<surname>Tiger</surname>
<name>Scott</name>
<salary>2222</salary>
</person>
</person>
</payment>
<payment>
<person>
<surname>BertJan</surname>
<name>Meinders</name>
<salary>3456</salary>
<salary>125</salary>
</person>
<person>
<surname>XYZ</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
</payment>
<payment>
<person>
<surname>Chris</surname>
<name>Gralike</name>
<salary>4567</salary>
</person>
<person>
<surname>LMN</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
</payment>
</payments>');
您可以使用此:
update t
set txt = to_clob(deletexml(
xmltype(t.txt),
'//payment/person[./name[text()="TEST"]]'
));
产生:
<?xml version="1.0" encoding="UTF-8"?>
<payments>
<payment>
<person>
<surname>Marco</surname>
<name>Gralike</name>
<salary>2345</salary>
</person>
</payment>
<payment>
<person>
<surname>BertJan</surname>
<name>Meinders</name>
<salary>3456</salary>
<salary>125</salary>
</person>
</payment>
<payment>
<person>
<surname>Chris</surname>
<name>Gralike</name>
<salary>4567</salary>
</person>
</payment>
</payments>
如果要删除没有给定子节点的节点,请使用以下命令:
update t
set txt = to_clob(deletexml(
xmltype(t.txt),
'//payment[not(./person)]'
));
它将删除所有没有人的付款标签。
deleteXML()已被弃用。 如果可能的话,您应该使用XQuery更新。 如果完整路径是固定的,也请尝试避免使用'//'。
with XML_TABLE as
(
select XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<payments>
<payment>
<person>
<surname>Marco</surname>
<name>Gralike</name>
<salary>2345</salary>
</person>
<person>
<surname>ABC</surname>
<name>TEST</name>
<salary>1234</salary>
<person>
<surname>Tiger</surname>
<name>Scott</name>
<salary>2222</salary>
</person>
</person>
</payment>
<payment>
<person>
<surname>BertJan</surname>
<name>Meinders</name>
<salary>3456</salary>
<salary>125</salary>
</person>
<person>
<surname>XYZ</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
</payment>
<payment>
<person>
<surname>Chris</surname>
<name>Gralike</name>
<salary>4567</salary>
</person>
<person>
<surname>LMN</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
</payment>
</payments>') as XML_COLUMN from dual
)
SELECT XMLQuery(
'copy $NEWXML := $XML modify (
delete nodes $NEWXML/payments/payment/person[name[text()=$NAME]]
)
return $NEWXML'
passing XML_COLUMN as "XML",
'TEST' as "NAME"
returning CONTENT
)
from XML_TABLE
/
您可以在livesql.oracle.com上尝试使用SQL Workbench删除此代码
感谢您的样品。
<payment>
<person>
<surname>XYZ</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
<id>person 4</id>
</payment>
如果节点之一包含上述数据,则在使用deletexml之后,我得到以下信息:
<payment>
<id>person 4</id>
</payment>
如果该节点不包含任何<person>
标记,如何删除?
即如何删除下面的节点,因为它不包含<person>
标签:
<payment>
<id>person 4</id>
</payment>
这有效
with XML_TABLE as
(
select XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>
<payments>
<payment>
<person>
<surname>XYZ</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
<id>person 4</id>
</payment>
<payment>
<id>person 5</id>
</payment>
</payments>') as XML_COLUMN from dual
)
SELECT XMLQuery(
'copy $NEWXML := $XML modify (
delete nodes $NEWXML/payments/payment[not(person)]
)
return $NEWXML'
passing XML_COLUMN as "XML",
'TEST' as "NAME"
returning CONTENT
)
from XML_TABLE
<?xml version="1.0" encoding="WINDOWS-1252"?>
<payments>
<payment>
<person>
<surname>XYZ</surname>
<name>TEST</name>
<salary>1234</salary>
</person>
<id>person 4</id>
</payment>
</payments>
SQL>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.