Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
检查XMLType节点值,必要时进行更新_Xml_Oracle_Oracle11g_Xmltype - Fatal编程技术网

检查XMLType节点值,必要时进行更新

检查XMLType节点值,必要时进行更新,xml,oracle,oracle11g,xmltype,Xml,Oracle,Oracle11g,Xmltype,我有一个简单的xml,如下所示: <Parameters> <Parameter> <Index>0</Index> <Name>Date</Name> <Value>@Today</Value> </Parameter> <Parameter> <Index>1</Index> <Name>Id</Name&

我有一个简单的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>
我希望遍历每个参数,如果该值以“@”开头,则调用一个函数,该函数将该值作为参数并返回一个新值。 使用newvalue更新xml。
我已经找到了如何使用updatexml,但没有找到实现我的方案的方法。

您可以通过每个参数节点循环执行,通过函数更改值我的代码中的内部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;

我有一个函数,它接受这个值@today->return today值2015年12月8日,@Dayed->returns 2015年12月7日etcI还没有尝试过,但我并不是只有@today作为一个标志,我有大约20个类似于@Dayed、@LastMonth等的标志。。所以我需要检查它是否从@开始。有什么解决方案吗?我添加了一个块,显示如何包含一些更改。谢谢,当我运行代码时,新的xml缺少我找到的值。我们需要在路径的末尾添加/text。所以它会变成:“/Parameters/Parameter/Value[text=@Today]/text”你能更新你的答案让我接受吗?它运行起来就像我在数据库中写的一样。不同版本的Oracle可能存在差异。我已经根据您的反馈进行了更新。