Is Oracle's EXTRACT function breaking the NOENTITYESCAPING in the XMLELEMENT?

前端 未结 1 622
无人共我
无人共我 2021-01-13 05:03

Oracle 11g. I figured out that if I add NOENTITYESCAPING to the XMLELEMENT function, it nicely turns off entity escaping. However, when I then pass

相关标签:
1条回答
  • 2021-01-13 05:42

    Try to use extractvalue() function, which unescapes encoded entities, instead of extract(). Here is an example:

    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)
    

    Result:

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

    But the use of extractvalue() function may be limited by the fact that it can return value of only one node. In a case of returning values of multiple nodes the utl_i18n package, and unescape_reference() function of that package can be used to unescape encoded entities:

    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;
    

    Result:

    RES                
    --------------------
    ><                   
    ><                   
    >< 
    

    Yes, as utl_i18n.unescape_reference() function accepts only values of varchar2 data type and types that can be implicitly converted to the varchar2 data type, your hands are tied when it comes to processing large "strings". In this situation you may turn to dbms_xmlgen package and convert() function in particular, which has an overloaded version capable of accepting CLOBs. Here is an example:

    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  
    

    Result:

    RES
    ------------------------------------------------------
    ><><><><><><><><><><><><><><><><><><><><><><><><><>
    -- ... the rest of the CLOB
    
    0 讨论(0)
提交回复
热议问题