Escaping control characters in Oracle XDB

后端 未结 4 1216
南旧
南旧 2020-12-11 23:42

I\'m completely new to Oracle\'s XDB, in particular using it to generate XML output from a database table, and am working on an application which is moving from 9i (Oracle9i

相关标签:
4条回答
  • 2020-12-11 23:45

    U+0013 is not a valid unicode codepoint for XML. See e.g. Valid characters in XML. So 11g correctly raises an exception.

    SQL> select xmlelement("test", unistr('a\0013b')) from dual;
    ERROR:
    ORA-31061: XDB error: special char to escaped char conversion failed.
    
    no rows selected
    
    SQL> select xmlelement("test", unistr('a\00aeb')) from dual;
    
    XMLELEMENT("TEST",UNISTR('A\00AEB'))
    --------------------------------------------------------------------------------
    <test>a®b</test>
    
    SQL> 
    

    No idea why this will pass in 9i (I don't have that available), but that's probably simply because Oracle's implementation has evolved to be more standard conforming and/or the standard has evolved.

    Your fix is correct.

    0 讨论(0)
  • 2020-12-11 23:45

    While always fixing the data at the source is the best solution, I also found this to be useful in the case where I cannot control the data at the source:

    select xmlelement("test", test) 
      from (select regexp_replace(unistr('a\0013b'), '[[:cntrl:]]', '') test from dual);
    

    Important piece is the regexp_replace(your_field, '[[:cntrl::]]', '') to remove control characters from the data.

    0 讨论(0)
  • 2020-12-11 23:55

    Just to follow-up on this for anyone interested. As far as I can tell, 9i just passed through the invalid character, producing invalid XML. 11g throws an error, which is probably the more correct behaviour, even if it is annoying in my case.

    The only reasonable solution I found was to fix the content at source.

    0 讨论(0)
  • 2020-12-12 00:07

    If you wish to keep line breaks, you may try like follows:

    select xmlelement("test", regexp_replace(test, '[^[:print:]|[:space:]]', '#')) from  
        (select '-   <- to keep line break after weird char
    -' test from dual ) 
    
    • replace all that ^ => is not in the sets (of printing [:print:] or space |[:space:] chars)
    0 讨论(0)
提交回复
热议问题