xml - Oracle XMLQUERY:如何根据子节点属性找到要删除的 XML 节点?
问题描述
你能帮我使下面的代码更健壮并避免硬编码吗?
我有以下代码:
SET SERVEROUTPUT ON SIZE UNLIMITED;
exec DBMS_OUTPUT.ENABLE (NULL);
set lines 1000
set define OFF
DECLARE
l_xml VARCHAR2(32767);
BEGIN
l_XML:='<?xml version="1.0"?> ';
l_XML:=l_XML||'<ROWSET> ';
l_XML:=l_XML||' <ROW> ';
l_XML:=l_XML||' <TABLE_T> ';
l_XML:=l_XML||' <VERS_MAJOR>2</VERS_MAJOR> ';
l_XML:=l_XML||' <CON0_LIST> ';
l_XML:=l_XML||' <CON0_LIST_ITEM> ';
l_XML:=l_XML||' <NAME>FAC2TS</NAME> ';
l_XML:=l_XML||' <CONTYPE>7</CONTYPE> ';
l_XML:=l_XML||' </CON0_LIST_ITEM> ';
l_XML:=l_XML||' </CON0_LIST> ';
l_XML:=l_XML||' <PROPERTY1>536870944</PROPERTY1>';
l_XML:=l_XML||' <CON2_LIST> ';
l_XML:=l_XML||' <CON2_LIST_ITEM> ';
l_XML:=l_XML||' <NAME>FACTS_PK</NAME> ';
l_XML:=l_XML||' <CONTYPE>3</CONTYPE> ';
l_XML:=l_XML||' </CON2_LIST_ITEM> ';
l_XML:=l_XML||' </CON2_LIST> ';
l_XML:=l_XML||' <PROPERTY>536870944</PROPERTY> ';
l_XML:=l_XML||' <CON1_LIST> ';
l_XML:=l_XML||' <CON1_LIST_ITEM> ';
l_XML:=l_XML||' <NAME>FACTS_PK</NAME> ';
l_XML:=l_XML||' <CONTYPE>2</CONTYPE> ';
l_XML:=l_XML||' </CON1_LIST_ITEM> ';
l_XML:=l_XML||' </CON1_LIST> ';
l_XML:=l_XML||' <REFPAR_LEVEL>0</REFPAR_LEVEL> ';
l_XML:=l_XML||' </TABLE_T> ';
l_XML:=l_XML||' </ROW> ';
l_XML:=l_XML||'</ROWSET> ';
SELECT XMLSERIALIZE( CONTENT
XMLQUERY( 'copy $i := $p modify delete nodes $i/ROWSET[1]/ROW[1]/TABLE_T[1]/CON1_LIST[1] return $i'
PASSING XMLTYPE(l_XML) AS "p"
RETURNING CONTENT
)
INDENT SIZE=2
)
INTO l_xml
FROM dual;
DBMS_OUTPUT.PUT_Line(l_XML);
END;
/ROWSET[1]/ROW[1]/TABLE_T[1]/CON1_LIST[1]
是要删除的硬编码值。实际上,我需要删除一个<CON*_LIST_ITEM>
包含<CONTYPE>2</CONTYPE>
.
你能帮助完成这项工作的 XMLQUERY 吗?
解决方案
您可以通过正则表达式及其子节点CONTYPE过滤所有子节点的名称:
//*[fn:matches(name(),"^CON\D+_LIST$") and ./*/CONTYPE="2"]
完整示例:
DECLARE
l_xml VARCHAR2(32767);
BEGIN
l_XML:='<?xml version="1.0"?> ';
l_XML:=l_XML||'<ROWSET> ';
l_XML:=l_XML||' <ROW> ';
l_XML:=l_XML||' <TABLE_T> ';
l_XML:=l_XML||' <VERS_MAJOR>2</VERS_MAJOR> ';
l_XML:=l_XML||' <CON0_LIST> ';
l_XML:=l_XML||' <CON0_LIST_ITEM> ';
l_XML:=l_XML||' <NAME>FAC2TS</NAME> ';
l_XML:=l_XML||' <CONTYPE>7</CONTYPE> ';
l_XML:=l_XML||' </CON0_LIST_ITEM> ';
l_XML:=l_XML||' </CON0_LIST> ';
l_XML:=l_XML||' <PROPERTY1>536870944</PROPERTY1>';
l_XML:=l_XML||' <CON2_LIST> ';
l_XML:=l_XML||' <CON2_LIST_ITEM> ';
l_XML:=l_XML||' <NAME>FACTS_PK</NAME> ';
l_XML:=l_XML||' <CONTYPE>3</CONTYPE> ';
l_XML:=l_XML||' </CON2_LIST_ITEM> ';
l_XML:=l_XML||' </CON2_LIST> ';
l_XML:=l_XML||' <PROPERTY>536870944</PROPERTY> ';
l_XML:=l_XML||' <CON1_LIST> ';
l_XML:=l_XML||' <CON1_LIST_ITEM> ';
l_XML:=l_XML||' <NAME>FACTS_PK</NAME> ';
l_XML:=l_XML||' <CONTYPE>2</CONTYPE> ';
l_XML:=l_XML||' </CON1_LIST_ITEM> ';
l_XML:=l_XML||' </CON1_LIST> ';
l_XML:=l_XML||' <REFPAR_LEVEL>0</REFPAR_LEVEL> ';
l_XML:=l_XML||' </TABLE_T> ';
l_XML:=l_XML||' </ROW> ';
l_XML:=l_XML||'</ROWSET> ';
SELECT
XMLSERIALIZE(
CONTENT
XMLQUERY(
'copy $i := $p
modify
delete nodes
$i//*[fn:matches(name(),"^CON\D+_LIST$") and ./*/CONTYPE="2"]
return $i'
PASSING XMLTYPE(l_XML) AS "p"
RETURNING CONTENT
)
INDENT SIZE=2
)
INTO l_xml
FROM dual;
DBMS_OUTPUT.PUT_Line(l_XML);
END;
/
推荐阅读
- node.js - 无法向客户发送呼叫
- javascript - 覆盖窗口作为函数调用上下文
- hadoop - Hive 托管表删除不会删除 HDFS 上的文件。有什么解决办法吗?
- asp.net - 将变量从 AJAX 表发送到 ASP.NET MVC 控制器
- batch-file - 使用 set 命令显示一个经常更新的号码
- javascript - vuejs 中“npm run serve”和“npm run dev”的区别
- c# - 如何从其他 razorpages 访问 razorpages 中的代码
- javascript - 输入不改变状态 REACTJS
- node.js - 在运行时更改节点全局变量
- ios - addArrangedSubview 与 addSubview