检查 XMLType 节点值并在必要时更新
Check XMLType node value and update if necessary
我有一个像这样的简单 xml:
<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
</Parameters>
我想遍历每个参数,如果值以“@”开头,则调用一个函数,该函数将值作为参数,returns 一个新值。
使用新值更新 xml.
我找到了如何使用更新xml,但没有运气如何实现我的场景。
您可以通过每个参数节点循环执行,通过函数更改值(我的代码中的内部 CheckXmlValue
)-
declare
cur_xml sys_refcursor;
v_val varchar2(3000);
n_val varchar2(3000);
xml_ XMLType := XMLType(
'<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
</Parameters>'
);
function CheckXmlValue(val_ in varchar2) return varchar2 is
begin
return
case lower(val_)
when '@today' then to_char(sysdate, 'dd/mm/yyyy')
when '@yesterday' then to_char(sysdate-1, 'dd/mm/yyyy')
else val_
end;
end;
begin
open cur_xml for
select extractValue(column_value, '//Value') str
from table(XMLSequence(extract(xml_, '/Parameters/Parameter')));
loop
fetch cur_xml into v_val;
n_val := CheckXmlValue(v_val);
exit when cur_xml%notfound;
select updateXml (
xml_,
'//Parameters/Parameter/Value[text()="'||v_val||'"]/text()',
n_val
)
into xml_
from DUAL;
end loop;
close cur_xml;
-- result:
dbms_output.put_line(xml_.extract('*').getStringVal());
end;
/
这个怎么样?如果在 PL*SQL 中使用,只需使用函数即可。
select updatexml(xmltype('<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
</Parameters>'), '/Parameters/Parameter/Value[text()="@Today"]', to_char(sysdate, 'dd/mm/yyyy'))
from dual;
注意是我调用的函数,需要的话换成你自己的。
对于许多不同的变体,只需在 upatexml 中添加一个又一个这样的更改,例如:
select updatexml(xmltype('<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
<Parameter>
<Index>2</Index>
<Name>Id</Name>
<Value>@Yesterday</Value>
</Parameter>
</Parameters>'), '/Parameters/Parameter/Value[text()="@Today"]/text()' , to_char(sysdate , 'dd/mm/yyyy')
, '/Parameters/Parameter/Value[text()="@Yesterday"]/text()', to_char(sysdate - 1, 'dd/mm/yyyy'))
from dual;
我有一个像这样的简单 xml:
<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
</Parameters>
我想遍历每个参数,如果值以“@”开头,则调用一个函数,该函数将值作为参数,returns 一个新值。
使用新值更新 xml.
我找到了如何使用更新xml,但没有运气如何实现我的场景。
您可以通过每个参数节点循环执行,通过函数更改值(我的代码中的内部 CheckXmlValue
)-
declare
cur_xml sys_refcursor;
v_val varchar2(3000);
n_val varchar2(3000);
xml_ XMLType := XMLType(
'<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
</Parameters>'
);
function CheckXmlValue(val_ in varchar2) return varchar2 is
begin
return
case lower(val_)
when '@today' then to_char(sysdate, 'dd/mm/yyyy')
when '@yesterday' then to_char(sysdate-1, 'dd/mm/yyyy')
else val_
end;
end;
begin
open cur_xml for
select extractValue(column_value, '//Value') str
from table(XMLSequence(extract(xml_, '/Parameters/Parameter')));
loop
fetch cur_xml into v_val;
n_val := CheckXmlValue(v_val);
exit when cur_xml%notfound;
select updateXml (
xml_,
'//Parameters/Parameter/Value[text()="'||v_val||'"]/text()',
n_val
)
into xml_
from DUAL;
end loop;
close cur_xml;
-- result:
dbms_output.put_line(xml_.extract('*').getStringVal());
end;
/
这个怎么样?如果在 PL*SQL 中使用,只需使用函数即可。
select updatexml(xmltype('<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
</Parameters>'), '/Parameters/Parameter/Value[text()="@Today"]', to_char(sysdate, 'dd/mm/yyyy'))
from dual;
注意是我调用的函数,需要的话换成你自己的。
对于许多不同的变体,只需在 upatexml 中添加一个又一个这样的更改,例如:
select updatexml(xmltype('<Parameters>
<Parameter>
<Index>0</Index>
<Name>Date</Name>
<Value>@Today</Value>
</Parameter>
<Parameter>
<Index>1</Index>
<Name>Id</Name>
<Value>22</Value>
</Parameter>
<Parameter>
<Index>2</Index>
<Name>Id</Name>
<Value>@Yesterday</Value>
</Parameter>
</Parameters>'), '/Parameters/Parameter/Value[text()="@Today"]/text()' , to_char(sysdate , 'dd/mm/yyyy')
, '/Parameters/Parameter/Value[text()="@Yesterday"]/text()', to_char(sysdate - 1, 'dd/mm/yyyy'))
from dual;