Страницы

Поиск по вопросам

пятница, 7 июня 2019 г.

Распарсить XML с xmltype() с обработкой исключений в запросе

Есть запрос:
select nvl(extractvalue(xmltype(p.src_doc, 871), '//*:' || pd.name), extractvalue(xmltype(p.src_doc, 871), '*/*[local-name()="AdditionalData"][*[local-name()="Name"]="' || pd.name || '"][1]/*[local-name()="Value"]')) as elm_value, pd.guid as param_guid, p.guid as pmnt_guid from payments p join services s on p.srv_guid = s.guid join parameters_definitions pd on s.guid = pd.srv_guid left outer join pmnt_elements_values elm on p.guid = elm.pmnt_guid and pd.guid = elm.param_guid where elm.guid is null and p.src_doc is not null;
В принципе корректно парсит XML в clob, но иногда может возникнуть исключение:
ORA-31011: сбой разбора XML ORA-19202: Возникла ошибка при обработке XML LPX-00601: Invalid token in: '//*: PAYMENTTYPE ' 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.
Проблема в том, что некоторые XML корректны, некоторые нет, таблица довольно объемна. Единого примера XML тоже дать не могу, так как все XML-документы корректны в рамках своей схемы, но по понятным причинам имеют разные значения в нодах, разные неймспейсы и атрибуты в некоторых нодах.
Можно ли как-то обойти/проигнорировать/обработать исключения разбора XML? Можно ли хотя бы как-то получить понимание где конкретно и на чем разваливается парсер?
Версия: Oracle Database 11g Enterprise Edition.


Ответ

Надо обернуть всю логику по разбору XML в функцию, которая обработает исключения и запишет полную информацию об ошибках, например, в таблицу. Как-то так:
create table parseErrors (guid raw (16), errm varchar2 (4000), created timestamp);
create or replace function myXmlParser (docGuid raw, doc clob) return varchar2 is procedure saveParseError (guid raw, errm varchar2) is pragma autonomous_transaction; begin insert into parseErrors values (guid, errm, systimestamp); commit; end ; begin -- **здесь необходимая логика, в которой может возникнуть ошибка** return xmlType (doc).getStringVal (); exception when others then saveParseError (docGuid, sqlerrm||chr(10)||sys.dbms_utility.format_error_backtrace()); return 'errorneous'; end myXmlParser; /
Выборка для теста (вместо sys_guid() должна быть колонка с GUID из запроса):
select myXmlParser (sys_guid(), 'some data') from dual union all select myXmlParser (sys_guid(), 'illegal XML syntax') from dual ;
выведет:
RESULT ------------------------ some data errorneous
Kакие были ошибки:
set lines 999 col errm for a40 wrapp select * from parseErrors;
GUID ERRM CREATED -------------------------------- ---------------------------------------- ----------------------------- 7106268B980F02D3E0530A01A8C04FBB ORA-31011: XML parsing failed 2018-07-15 12:32:41,204757000 ORA-06512: at "SYS.XMLTYPE", line 272 ORA-06512: at "DB.MYXMLPARSER", line 10

PS В вопросе мало информации по локализации причины ошибки, но думаю ссылки на похожие топики тут и тут будут полезны.

Комментариев нет:

Отправить комментарий