Intenta usar extractvalue()
función, que elimina las entidades codificadas, en lugar de extract()
. Aquí hay un ejemplo:
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->
Pero el uso de extractvalue()
La función puede estar limitada por el hecho de que puede devolver el valor de un solo nodo. En el caso de devolver valores de múltiples nodos, utl_i18n
paquete y unescape_reference()
La función de ese paquete se puede usar para eliminar las 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
--------------------
><
><
><
Sí, como utl_i18n.unescape_reference()
la función solo acepta valores de varchar2
tipo de datos y tipos que se pueden convertir implícitamente a varchar2
tipo de datos, sus manos están atadas cuando se trata de procesar grandes "cadenas ". En esta situación, puede recurrir a dbms_xmlgen
paquete y convert()
función en particular, que tiene una versión sobrecargada capaz de aceptar CLOB
s. He aquí un ejemplo:
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