Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

A função EXTRACT do Oracle está quebrando o NOENTITYESCAPING no XMLELEMENT?


Tente usar extractvalue() função, que não escapa de entidades codificadas, em vez de extract() . Aqui está um exemplo:
clear screen;
column res format a20;

-- depending on a situation, NOENTITYESCAPING might be dropped

select extractvalue(
                     xmlelement(NOENTITYESCAPING e,id,'->')
                    , '//text()'
                    ) as res
  from (select level as id 
          from dual 
       connect by level < 6)

Resultado:
RES                
--------------------
1->                  
2->                  
3->                  
4->                  
5->    

Mas o uso de extractvalue() A função pode ser limitada pelo fato de poder retornar o valor de apenas um nó. No caso de retornar valores de vários nós, o utl_i18n pacote e unescape_reference() A função desse pacote pode ser usada para liberar entidades codificadas:
clear screen;
column res format a20;

select utl_i18n.unescape_reference(xmlelement(root
                                             , xmlelement(node1, '>')
                                             , xmlelement(node2, '<')
                                             ).extract('//text()').getstringval()
                                   ) as res
 from dual
connect by level <= 3;

Resultado:
RES                
--------------------
><                   
><                   
>< 

Sim, como utl_i18n.unescape_reference() função aceita apenas valores de varchar2 tipo de dados e tipos que podem ser convertidos implicitamente para o varchar2 tipo de dados, suas mãos estão atadas quando se trata de processar grandes "strings ". Nesta situação, você pode recorrer a dbms_xmlgen pacote e convert() função em particular, que tem uma versão sobrecarregada capaz de aceitar CLOB s. Aqui está um exemplo:
select dbms_xmlgen.convert(
                           xmlagg(xmlelement(root
                                             , xmlelement(node1, '>')
                                             , xmlelement(node2, '<')
                                             )
                                  ).extract('//text()').getclobval()
                          , 1) as res
 from dual
connect by level <= 3000;   -- 1 (second parameter of the convert() function)
                            -- instructs function to decode entities  

Resultado:
RES
------------------------------------------------------
><><><><><><><><><><><><><><><><><><><><><><><><><>
-- ... the rest of the CLOB