Как читать данные XMLTYPE, но пространство имен в SQL / PLSQL (Oracle) - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть этот фрагмент данных XML в файле

<?xml version="1.0" encoding="UTF-8"?>

-<p:FatturaElettronica xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" versione="FPR12">

Это корневой тег.Сейчас я пытаюсь извлечь данные.Я использую xpath, поскольку файл более сложный.Я успешно смог прочитать данные перед пространством имен, используя EXISTSNODE() и EXTRACT() метод XMLTYPE.

Теперь корневой тег изменен.Я не могу обработать пространство имен.Я смог обработать данные, определив пространство имен как:

DECLARE
l_ns_def VARCHAR2(240) := 'xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.1"';
BEGIN
IF l_xml.EXISTSNODE (l_common_path||'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice/text()',l_ns_def) > 0 THEN
l_sender_tic := l_xml.EXTRACT (l_common_path||'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice/text()',l_ns_def   ).GETSTRINGVAL ();
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(' EOOR - '||SQLERRM);
--END IF;
END;

Переменные, используемые l_sender_tic, - это VARCHAR2 (2000) L_COMMON_PATH = / p: FatturaElettronica, но я не могу сейчас извлечь данные.Ошибка возникает из-за того, что либо массив связывания слишком мал, либо ORA-30625: отправка метода по аргументу NULL SELF запрещена

Я полагаю, что проблема связана с корневым тегом.Файл имеет правильный синтаксис, который подтвержден.Пожалуйста, помогите мне в этом.

1 Ответ

0 голосов
/ 18 сентября 2018

Ваш код работает с XML, с которым вы связались:

DECLARE
  l_xml xmltype := xmltype(q'[<?xml version="1.0" encoding="UTF-8"?>
<p:FatturaElettronica xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" versione="1.1">
<FatturaElettronicaHeader>
...
</FatturaElettronicaBody>
</p:FatturaElettronica>]');

  l_sender_tic varchar2(4000);
  l_common_path varchar2(30) := '/p:FatturaElettronica/';
  l_ns_def VARCHAR2(240) := 'xmlns:p="http://www.fatturapa.gov.it/sdi/fatturapa/v1.1"';
BEGIN
  IF l_xml.EXISTSNODE (l_common_path||'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice/text()',l_ns_def) > 0 THEN
    l_sender_tic := l_xml.EXTRACT (l_common_path||'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice/text()',l_ns_def).GETSTRINGVAL ();
  END IF;
  dbms_output.put_line('Got: ' || l_sender_tic);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(' EOOR - '||SQLERRM);
END;
/

Got: 01234567890

PL/SQL procedure successfully completed.

Если корневой узел изменяется, как вы указали в начале вашего вопроса, тогда l_ns_def должен измениться, чтобы соответствовать:

DECLARE
  l_xml xmltype := xmltype(q'[<?xml version="1.0" encoding="UTF-8"?>
<p:FatturaElettronica xsi:schemaLocation="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2 http://www.fatturapa.gov.it/export/fatturazione/sdi/fatturapa/v1.2/Schema_del_file_xml_FatturaPA_versione_1.2.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" versione="FPR12">
<FatturaElettronicaHeader>
...
</FatturaElettronicaBody>
</p:FatturaElettronica>]');

  l_sender_tic varchar2(4000);
  l_common_path varchar2(30) := '/p:FatturaElettronica/';
  l_ns_def VARCHAR2(240) := 'xmlns:p="http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2"';
BEGIN
  IF l_xml.EXISTSNODE (l_common_path||'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice/text()',l_ns_def) > 0 THEN
    l_sender_tic := l_xml.EXTRACT (l_common_path||'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice/text()', l_ns_def).GETSTRINGVAL ();
  END IF;
  dbms_output.put_line('Got: ' || l_sender_tic);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE(' EOOR - '||SQLERRM);
END;
/

Got: 01234567890

PL/SQL procedure successfully completed.

Очень быстрый пример использования XMLTable для извлечения нескольких точек данных одновременно;при условии, что ваш XML-документ находится в your_table в столбце с именем xml:

select x.*
from your_table t
cross join xmltable(
  xmlnamespaces('http://ivaservizi.agenziaentrate.gov.it/docs/xsd/fatture/v1.2' as "p"),
  '/p:FatturaElettronica'
  passing t.xml
  columns IdPaese varchar2(8) path 'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdPaese',
    IdCodice number path 'FatturaElettronicaHeader/DatiTrasmissione/IdTrasmittente/IdCodice',
    CodiceFiscale number path 'FatturaElettronicaHeader/CessionarioCommittente/DatiAnagrafici/CodiceFiscale',
    Data date path 'FatturaElettronicaBody/DatiGenerali/DatiGeneraliDocumento/Data'
) x;

IDPAESE    IDCODICE CODICEFISCALE DATA       
-------- ---------- ------------- -----------
IT       1234567890    9876543210 18-Dec-2014

Это может усложниться в зависимости от структуры документа и того, что вы хотите извлечь, но это основная идея.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...