Search code examples
xmloracle-databaseoracle11gxmltype

Check XMLType node value and update if necessary


I have a simle xml like this:

<Parameters>
 <Parameter>
  <Index>0</Index>
  <Name>Date</Name>
  <Value>@Today</Value>
 </Parameter>
 <Parameter>
  <Index>1</Index>
  <Name>Id</Name>
  <Value>22</Value>
 </Parameter>
</Parameters>

I would like to iterate through each parameter and if the value starts with '@' called a function that takes as parameter the value and returns a new value.
Use the newvalue to update the xml.
I 've found how to use the updatexml, but no luck how to implement my scenario.


Solution

  • How about this? If using in PL*SQL, just use only the function.

      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;
    

    Note that it is a function I call, replace with your own if desiered.

    For many different variants, just add one such change after another in the upatexml such as:

      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;