I'm using an Oracle 18c view called GDB_ITEMS_VW that has XML data in a clob column.
I can extract data from the XML column using the following query (source):
select
x.code,
x.description,
i.name as domain_name
from
sde.gdb_items_vw i
cross apply xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(i.definition)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
) x
DOMAIN_NAME CODE DESCRIPTION
-------------------- -------------------- ----------------------------------------
ATN_MATERIAL A ASPHALT
ATN_MATERIAL O ASPHALT CAPPING
ATN_MATERIAL B BRICK
When I run that query in SQL Developer, it runs without errors, but that's just because it's only selecting the first 50 rows.
If I try to run the query on all rows (via CTRL+END), then it throws an error:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML processing
LPX-00007: unexpected end-of-file encountered
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.
So I want determine what specific rows are causing that error.
As mentioned by @MT0 in a related post, we can find the problem rows by:
Creating a function to wrap the call that is causing issues and catch the exception in the function.
I've attempted to adapt @MT0's function:
with function test_xmltable(v_xml clob) return number
is
temp xmltype;
begin
temp := xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(v_xml)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
);
return 1;
exception
when others then
return 0;
end;
select
i.name as domain_name,
test_xmltable(i.definition)
from
sde.gdb_items_vw i
where
test_xmltable(i.definition) = 0;
But I must be doing something wrong, because I'm getting an error:
ORA-00905: missing keyword
00905. 00000 - "missing keyword"
*Cause:
*Action:
Error at Line: 1 Column: 15
How can I find the problem XML values?
If your XML will return a single row, you can use:
with function test_xmltable(v_xml clob) return number
is
v_code VARCHAR2(255);
v_desc VARCHAR2(255);
begin
SELECT code, description
INTO v_code, v_desc
FROM xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(v_xml)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
);
return 1;
exception
when others then
return 0;
end;
select i.name as domain_name,
test_xmltable(i.definition)
from sde.gdb_items_vw i
where test_xmltable(i.definition) = 0;
If it will return multiple rows, you can use:
with function test_xmltable(v_xml clob) return number
is
v_code SYS.ODCIVARCHAR2LIST;
v_desc SYS.ODCIVARCHAR2LIST;
begin
SELECT code, description
BULK COLLECT INTO v_code, v_desc
FROM xmltable(
'/GPCodedValueDomain2/CodedValues/CodedValue'
passing xmltype(v_xml)
columns
code varchar2(255) path './Code',
description varchar2(255) path './Name'
);
return 1;
exception
when others then
return 0;
end;
select i.name as domain_name,
test_xmltable(i.definition)
from sde.gdb_items_vw i
where test_xmltable(i.definition) = 0;
db<>fiddle here