你能帮我让下面的代码更健壮并避免硬编码吗?
我有以下代码:
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]
是要删除的硬编码值。实际上,我需要删除包含<CONTYPE>2</CONTYPE>
的<CON*_LIST_ITEM>
节点(*是某个数字(。
你能帮助XMLQUERY完成这项工作吗?
您可以通过正则表达式及其子节点CONTYPE过滤所有子节点的名称://*[fn:matches(name(),"^COND+_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(),"^COND+_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;
/