Опитайте да използвате extractvalue()
функция, която премахва екранирането на кодирани обекти, вместо extract()
. Ето един пример:
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)
Резултат:
RES
--------------------
1->
2->
3->
4->
5->
Но използването на extractvalue()
функцията може да бъде ограничена от факта, че може да върне стойност само на един възел. В случай на връщане на стойности на множество възли utl_i18n
пакет и unescape_reference()
функцията на този пакет може да се използва за деекраниране на кодирани обекти:
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;
Резултат:
RES
--------------------
><
><
><
Да, като utl_i18n.unescape_reference()
функцията приема само стойности на varchar2
тип данни и типове, които могат да бъдат имплицитно преобразувани в varchar2
тип данни, ръцете ви са вързани, когато става въпрос за обработка на големи "низове ". В тази ситуация можете да се обърнете към dbms_xmlgen
пакет и convert()
по-специално функция, която има претоварена версия, способна да приема CLOB
с. Ето един пример:
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
Резултат:
RES
------------------------------------------------------
><><><><><><><><><><><><><><><><><><><><><><><><><>
-- ... the rest of the CLOB