1

I have a table having a XML Type column in Oracle DB. I am trying to use the extractvalue and updatexml functions on that table.

XML

<?xml version = '1.0' encoding = 'UTF-8'?>
<custominfo>
   <singlerecord  ZIP="51100"/>
   <multiplerecord type="ONE_TIME_CHARGES_LIST">
      <record DESCRIPTION="Device Payment" RATE="1000000" TAX="0"/>
      <record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>
      <record DESCRIPTION="Deposit" RATE="1000000" TAX="0"/>
   </multiplerecord>
</custominfo> 

Query

select EXTRACTVALUE(XMLCONTENT,'//record[@DESCRIPTION="Plan Payment"]') from TABLE_XML  X;

Can anyone suggest what I am doing wrong here?

After sorting out the extract I want to replace the DESCRIPTION from "Plan Payment" to "Pre Plan Payment".

1
  • 1
    Your record nodes have no content, only attributes; so what output are you expecting to see? Commented Jun 14, 2018 at 8:10

1 Answer 1

3

What you are doing is working - it's giving you the text value of the record node with that attribute value. But that node is empty:

<record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>

has three attributes but the node itself has no content - it's an empty tag. So your query is returning null, which is correct. If you wanted to see that you'd found the node you could get an attribute value instead:

select EXTRACTVALUE(XMLCONTENT,'//record[@DESCRIPTION="Plan Payment"]/@DESCRIPTION')
from TABLE_XML  X;

However, the extractvalue() function has long been deprecated, so you shouldn't really be using it anyway.

You can use an XMLQuery to view the whole matching record node; as the node has no content there isn't much point in getting its content, as your current query does:

select XMLQuery('$x//record[@DESCRIPTION="Plan Payment"]'
    passing xmlcontent as "x"
    returning content
  ) as result
from table_xml;

RESULT                                                                          
--------------------------------------------------------------------------------
<record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>

The updatexml() function is deprecated as well. You can use an XMLQuery to modify the attribute name too:

select XMLQuery('copy $i := $x modify
    (for $j in $i//record[@DESCRIPTION="Plan Payment"]/@DESCRIPTION
      return replace value of node $j with $r)
    return $i'
    passing xmlcontent as "x", 'Pre Plan Payment' as "r"
    returning content
  ) as result
from table_xml;

Using a CTE for your sample XML document, and wrapping it in an XMLSerialize call to retain the formatting for readability:

with table_xml (xmlcontent) as (
  select xmltype(q'[<?xml version = '1.0' encoding = 'UTF-8'?>
<custominfo>
   <singlerecord  ZIP="51100"/>
   <multiplerecord type="ONE_TIME_CHARGES_LIST">
      <record DESCRIPTION="Device Payment" RATE="1000000" TAX="0"/>
      <record DESCRIPTION="Plan Payment" RATE="480000" TAX="0"/>
      <record DESCRIPTION="Deposit" RATE="1000000" TAX="0"/>
   </multiplerecord>
</custominfo>]'
  ) from dual
)
select XMLSerialize(
    document
    XMLQuery('copy $i := $x modify
      (for $j in $i//record[@DESCRIPTION="Plan Payment"]/@DESCRIPTION
        return replace value of node $j with $r)
      return $i'
      passing xmlcontent as "x", 'Pre Plan Payment' as "r"
      returning content
    )
    indent
  ) as result
from table_xml;

RESULT                                                                          
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<custominfo>
  <singlerecord ZIP="51100"/>
  <multiplerecord type="ONE_TIME_CHARGES_LIST">
    <record DESCRIPTION="Device Payment" RATE="1000000" TAX="0"/>
    <record DESCRIPTION="Pre Plan Payment" RATE="480000" TAX="0"/>
    <record DESCRIPTION="Deposit" RATE="1000000" TAX="0"/>
  </multiplerecord>
</custominfo>

If you want to update the value in the table you can use the same query as part of an update statement, filtered on rows that match. Read more.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Alex. I am able to update using updatexml by your given syntax. although I am not able to use XMLQuery it is still returning null

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.