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