Oracle的EXTRACT功能是否打破了XMLELEMENT中的NOENTITYESCAPING?

Tro*_*ame 5 xml oracle escaping extract oracle11g

Oracle 11g.我想通过,如果我添加NOENTITYESCAPING到该XMLELEMENT函数,它很好地关闭实体转义.但是,当我将结果传递给EXTRACT逃逸似乎又回来了.

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

XMLELEMENT(NOENTITYESCAPINGE,ID,'->')
---------------------------------------
<E>1-></E>
<E>2-></E>
<E>3-></E>
<E>4-></E>
<E>5-></E>
Run Code Online (Sandbox Code Playgroud)

现在,添加EXTRACT:

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

XMLELEMENT(NOENTITYESCAPINGE,ID,'->').EXTRACT('//TEXT()')
----------------------------------------------------------
1-&gt;
2-&gt;
3-&gt;
4-&gt;
5-&gt;
Run Code Online (Sandbox Code Playgroud)

是否有任何修复/解决方法可以关闭转义?该手册给出了没有任何帮助.

Nic*_*nov 13

尝试使用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)
Run Code Online (Sandbox Code Playgroud)

结果:

RES                
--------------------
1->                  
2->                  
3->                  
4->                  
5->    
Run Code Online (Sandbox Code Playgroud)

但是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;
Run Code Online (Sandbox Code Playgroud)

结果:

RES                
--------------------
><                   
><                   
>< 
Run Code Online (Sandbox Code Playgroud)

是的,因为utl_i18n.unescape_reference()函数只接受varchar2可以隐式转换为varchar2数据类型的数据类型和类型的值,所以当涉及处理大的" 字符串 " 时,你的双手就被束缚了.在这种情况下,您可能会转向特别是dbms_xmlgenpackage和convert()函数,它具有能够接受CLOBs 的重载版本.这是一个例子:

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  
Run Code Online (Sandbox Code Playgroud)

结果:

RES
------------------------------------------------------
><><><><><><><><><><><><><><><><><><><><><><><><><>
-- ... the rest of the CLOB
Run Code Online (Sandbox Code Playgroud)

  • @TrojanName`我认为这也达到了4000个字符限制.是的.`unescape_reference()`函数接受`varchar2`值.要处理"*big*"字符串,请使用`dbms_xmlgen.convert()`函数.答案已更新. (2认同)