Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Chris.

Asked: April 28, 2017 - 6:40 pm UTC

Last updated: May 01, 2017 - 7:12 am UTC

Version: 12.0c

Viewed 1000+ times

You Asked

I'm trying to extract specific fields from XML in a CLOB field. Unfortunately, it isn't stored as XMLTYPE, so I'm doing:

EXTRACTVALUE(xmltype(ctr.rule_text), 'configuration/criteria/text()')

Most of the values in the DB are valid XML, but some are not. They have additional text after the final closing tag and I get this error:

ORA-31011: XML parsing failed
ORA-19213: error occurred in XML processing at lines 17
LPX-00245: extra data after end of document
ORA-06512: at "SYS.XMLTYPE", line 272
ORA-06512: at line 1
31011. 00000 - "XML parsing failed"
*Cause: XML parser returned an error while trying to parse the document.
*Action: Check if the document to be parsed is valid.

I'm fine to skip these rows if there was a way to know if the field is valid XML first before trying an extract on it.
Didn't find any solutions yet.

and Connor said...

Mark Drake (the XML product manager) wrote up some excellent examples on this forum post

https://community.oracle.com/thread/418458

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

XML wellformedness check

Marc Bleron, April 29, 2017 - 9:52 am UTC

If you only want to filter out those rows that don't contain a wellformed XML document, then you'll need a separate function you can use in a WHERE clause.
The function just has to build an XMLType instance from the CLOB and returns 1 if no exception is raised, or 0 otherwise.

It can be defined at schema level (allowing creation of a function-based index, if necessary) or transiently in the SQL statement itself (12c feature).
Here's an example of the latter :
SQL> create table configuration (id integer, rule_text clob);

Table created.

SQL> insert into configuration values (1, '<configuration><criteria>1234</criteria></configuration>');

1 row created.

SQL> insert into configuration values (2, '<configuration><criteria>4567</criteria></configuration> some extra information');

1 row created.

SQL>
SQL> with function XMLIsWellformed (p_xml in clob) return integer
  2  is
  3    l_xml  xmltype;
  4  begin
  5    l_xml := xmltype(p_xml);
  6    return 1;
  7  exception
  8    when others then
  9      return 0;
 10  end;
 11  select t.id
 12       , xmlcast(
 13           xmlquery('/configuration/criteria' passing xmlparse(document t.rule_text) returning content)
 14           as number
 15         ) as val
 16  from configuration t
 17  where XMLIsWellformed(t.rule_text) = 1
 18  /

        ID        VAL
---------- ----------
         1       1234

Please also note the usage of XMLCAST/XMLQUERY construct to extract scalar values. You may also use XMLTABLE.
EXTRACTVALUE function is deprecated.



Connor McDonald
May 01, 2017 - 7:12 am UTC

Thanks for the input

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here