Erro de parsing ao ler XML - FDPSTP, ORA-31011, LPX-00283

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

Bom dia pessoal
fiz uma rotina para ler arquivos XML de uma pasta. Alguns xml lê normalmente, mas outras dão o erro:
Causa: Ocorreu um erro em FDPSTP, porque ORA-31011: falha no parse XML
ORA-19202: Ocorreu um erro no processamento XML
LPX-00283: a codificação de documento baseia-se em UTF-8, mas a codificação de entrada default não
xml que consigo ler:

Selecionar tudo

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
xml que não consigo ler:

Selecionar tudo

<?xml version="1.0" encoding="UTF-8"?>
Fiz o select abaixo:

Selecionar tudo

SELECT VALUE
  FROM SYS.nls_database_parameters
 WHERE parameter = 'NLS_CHARACTERSET'
o resultado é:

Selecionar tudo

WE8ISO8859P1
o erro ocorre quando faço esta atribuição dentro da rotina:

Selecionar tudo

            AuxXML := XMLType.createxml(AuxConteudo);
sendo que:

Selecionar tudo

AuxConteudo CLOB;
AuxXML xmltype;
pode me dar uma ajuda por favor ?
obrigado
att,
Marlon
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Aqui tem algumas explicações sobre o standalone.
https://stackoverflow.com/questions/557 ... ean-in-xml

Você poderia anexar aqui um exemplo de XML funcionando e outro não?
Acho que tem algo com as tags que você está utilizando.
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

boa tarde
segue exemplo de xml em anexo
Anexos
nao_funciona.xml
(7.73 KiB) Baixado 170 vezes
funciona.xml
(13.36 KiB) Baixado 177 vezes
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Eu vi uma solução pra um erro semelhante assim: (Doc ID 1302083.1)

Código original: (Não funcionando)

Selecionar tudo

DECLARE
    parser                  xmlParser.parser;
    newDomDoc               xmlDom.domDocument;
    retdoc                  xmlDom.domDocument;
    newElem                 xmlDom.domElement;
BEGIN                
    parser := xmlParser.newParser;
    xmlparser.parse(parser,'/home/scott/test.xml');
    retdoc := xmlParser.getDocument(parser);
    newElem:=xmlDom.getDocumentElement(retdoc);
END;
/
O XML possui um caracter na primeira linha:

Selecionar tudo

\220\221<?xml version="1.0" encoding="utf-16"?>
Quando esse 220, 221 é removido, o xml roda normal.

Sugestão:
Criar um diretório

Selecionar tudo

create or replace directory XMLTSTDIR as '/home/scott';
Criar uma procedure que LE o xml e guarda num clob:

Selecionar tudo

create or replace function getDocument(filename varchar2,chrset varchar2 default 'UTF8') return clob authid current_user is
   xbfile bfile;
   xclob clob;
   destination_offset INTEGER := 1;
   source_offset INTEGER := 1;
   language_context INTEGER := DBMS_LOB.default_lang_ctx;
   warning_message INTEGER;
begin
   xbfile := bfilename('XMLTSTDIR',filename);
   dbms_lob.open(xbfile);
   dbms_lob.createtemporary(xclob,TRUE,dbms_lob.session);
   DBMS_LOB.LOADCLOBFROMFILE(xclob,xbfile, dbms_lob.getlength(xbfile), destination_offset, source_offset,NLS_CHARSET_ID(chrset),language_context, warning_message);
   dbms_lob.close(xbfile);
   return xclob;
end;
/
Chamar a nova procedure:

Selecionar tudo

DECLARE
   parser dbms_xmlparser.parser;
   newDomDoc xmlDom.domDocument;
   retdoc clob;
   newElem xmlDom.domElement;
BEGIN
   parser := xmlParser.newParser;
   retdoc := getDocument('SampleOriginal.xml','AL16UTF16LE');
   DBMS_XMLPARSER.PARSECLOB(parser,retdoc);
   newDomDoc := xmlParser.getDocument(parser);
   newElem:=xmlDom.getDocumentElement(newDomDoc);
END;
/

PL/SQL procedure successfully completed.
Vou dar uma olhada nos anexos que você mandou.
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Eu abri os 2 arquivos que você mandou num editor HEXA.
Veja que o seu XML possui 3 caracteres loucos antes do XML:
xml_problem.png
Acho que a solução proposta pela ORACLE é muito semelhante a isso.
Acho que vale a pena tentar criar aquela procedure. :-o
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

Boa tarde
infelizmente ainda não deu certo.

quando faço:

Selecionar tudo

   retdoc := getDocument(x.name,'UTF-8');
dá o erro:
Causa: Ocorreu um erro em FDPSTP, porque ORA-06502: PL/SQL: erro numérico ou de valor
ORA-06512: em "SYS.DBMS_LOB", line 960
ORA-06512: em "APPS.GETDOCUMENT", line 12
que dentro da função criada, é na linha:

Selecionar tudo

   DBMS_LOB.LOADCLOBFROMFILE(xclob,xbfile, dbms_lob.getlength(xbfile), destination_offset, source_offset,NLS_CHARSET_ID(chrset),language_context, warning_message);
Não sei se entendi bem, mas o objetivo desta função é retirar aqueles caracteres no início do XML ?
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Não, o objetivo daqueles 2 programas é
1. Carregar o XML pra dentro de uma variável CLOB
2. Depois que está dentro do CLOB, utilizar o DBMS_XMLPARSER.PARSECLOB

Conforme o DOC da Oracle, dessa forma teria que funcionar.
Você tentou carregar o XML sem os 3 caracteres no início ? (Só por curiosidade, pra ver se funciona).
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Tentei aqui e deu certo!
1. Copiei o "não_funciona.xml" pra dentro do diretório TMP.
2. Criei essa package: (igual aquela que eu passei la em cima, só mudei o diretório pra TMP)

Selecionar tudo

create or replace function thomas_getDocument(filename varchar2,chrset varchar2 default 'UTF8') return clob authid current_user is
   xbfile bfile;
   xclob clob;
   destination_offset INTEGER := 1;
   source_offset INTEGER := 1;
   language_context INTEGER := DBMS_LOB.default_lang_ctx;
   warning_message INTEGER;
begin
   xbfile := bfilename('TMP',filename);
   dbms_lob.open(xbfile);
   dbms_lob.createtemporary(xclob,TRUE,dbms_lob.session);
   DBMS_LOB.LOADCLOBFROMFILE(xclob,xbfile, dbms_lob.getlength(xbfile), destination_offset, source_offset,NLS_CHARSET_ID(chrset),language_context, warning_message);
   dbms_lob.close(xbfile);
   return xclob;
end;
3. Executei esse programa: (mudei o nome do arquivo E tirei fora o AL16UTF16LE, pra ele usar UTF8)

Selecionar tudo

DECLARE
   parser dbms_xmlparser.parser;
   newDomDoc xmlDom.domDocument;
   retdoc clob;
   newElem xmlDom.domElement;
BEGIN
   parser := xmlParser.newParser;
   retdoc := thomas_getDocument('não_funciona.xml'); --,'AL16UTF16LE'
   DBMS_XMLPARSER.PARSECLOB(parser,retdoc);
   newDomDoc := xmlParser.getDocument(parser);
   newElem:=xmlDom.getDocumentElement(newDomDoc);
END;
Deu certo! Veja onde eu comentei acima...
Quando eu executo com AL16UTF16LE não funciona, dá a mesma mensagem que você está tendo.
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

me dá uma ajuda por favor:
veja a minha rotina. Eu leio todos os .xml que estão em uma pasta e insiro em uma tabela (pcn_xml)
veja o comentário onde ocorre o erro:

Selecionar tudo

PROCEDURE PCN_RI_CARGA_XML ( errbuf          out  varchar2,
                       retcode         out  varchar2)   is

         l_blob    blob;
         l_bfile   bfile;
         l_dir     varchar2(30) default 'XML_REC_DIR';
         AuxNomeDiretorio varchar2(100) := 'XML_REC_DIR';
         AuxNomeArquivo varchar2(150); 
         AuxArquivo Bfile;
         AuxConteudo CLOB;
         AuxXML xmltype;
         contador number := 1;
         Existe   number := 0;

         parser dbms_xmlparser.parser;
         newDomDoc xmlDom.domDocument;
         retdoc clob;
         newElem xmlDom.domElement;

BEGIN

    begin
         for x in ( select name from table(util.ls(l_dir)) where name like '%.xml')
         loop

            parser := xmlParser.newParser;
            retdoc := getDocument(x.name); 

            DBMS_XMLPARSER.PARSECLOB(parser,retdoc);
            newDomDoc := xmlParser.getDocument(parser);
            newElem:=xmlDom.getDocumentElement(newDomDoc);

            AuxNomeArquivo := x.name;
            AUXArquivo     := bfilename(AuxNomeDiretorio,AuxNomeArquivo);
            DBMS_LOB.fileOpen(AuxArquivo,dbms_lob.file_readonly);
            DBMS_LOB.createtemporary(retdoc,TRUE,DBMS_LOB.session);
            DBMS_LOB.loadFromFile(retdoc,AuxArquivo,DBMS_LOB.getLength(AuxArquivo),1,1);
            DBMS_LOB.fileClose(AuxArquivo);

            ---- nessa linha é que ocorre o erro
            AuxXML := XMLType.createxml(retdoc);

            Insert Into APPS.pcn_xml(registro,creation_date,nomearq,nota) values(Contador,sysdate,x.name,AuxXML);


        end loop;
   end;


END PCN_RI_CARGA_XML;

Estrutura da tabela PCN_XML

Selecionar tudo

REGISTRO                    NOT NULL NUMBER(10)     
CREATION_DATE               DATE           
NOMEARQ                     VARCHAR2(250)  
NOTA                        PUBLIC.XMLTYPE 
PROCESSADO                  VARCHAR2(1)    
DATA_PROCESSAMENTO          DATE
marlonpasquali
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 248
Registrado em: Sex, 06 Fev 2009 3:02 pm
Localização: ERECHIM - RS

bom dia
consegui resolver da seguinte maneira:

tratei apenas meu insert desta forma. Então não precisei fazer os outros comandos que davam erro.

Selecionar tudo

Insert Into APPS.pcn_xml(registro,creation_date,nomearq,nota) 
values(Contador,
      sysdate,
      x.name,
      XMLTYPE(BFILENAME('XML_REC_DIR', x.name), NLS_CHARSET_ID('UTF-8')));

obrigado pelas dicas.
abraço !!!
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 15 visitantes