转义Oracle XDB中的控制字符

时间:2011-09-01 12:42:53

标签: xml oracle control-characters

我是Oracle XDB的新手,特别是使用它来从数据库表生成XML输出,并正在开发一个从9i(Oracle9i企业版9.2.0.5.0版 - 生产版)迁移到的应用程序11g(Oracle数据库11g企业版11.2.0.2.0版 - 64位生产)。这是一个小测试用例,说明了我遇到的问题:

select xmlelement("test", test) from (select 'a' test from dual);

这有效并且给了我:

<test>a</test>

然而在11g中,如果我将'a'换成无效字符,例如U + 0013,我会收到以下错误:

ORA-31061: XDB error: special char to escaped char conversion failed.

在9i下,同样的功能成功,没有错误。

显然,理想的答案是进行一些验证以防止控制字符进入我试图转换为XML的简单字符数据,但不幸的是,这超出了我正在做的范围。

这是否是其他任何人都经历过的事情,如果是这样,我可以对我的XML生成脚本进行简单的更改,还是需要进行其他类型的清理?或者只是在极少数情况下手动修复问题(这对我的需求来说是一个非常合理的选择)。

非常感谢。

4 个答案:

答案 0 :(得分:4)

虽然总是在源头修复数据是最好的解决方案,但我也发现这对我无法在源头控制数据的情况很有用:

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

重要的部分是regexp_replace(your_field,'[[:cntrl ::]]','')从数据中删除控制字符。

答案 1 :(得分:3)

U + 0013不是XML的有效unicode代码点。参见例如Valid characters in XML。所以11g正确引发了异常。

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> 

不知道为什么会传入9i(我没有那个),但这可能只是因为Oracle的实现已经发展为更符合标准和/或标准已经发展。

你的修正是正确的。

答案 2 :(得分:0)

只是对任何感兴趣的人进行跟进。据我所知,9i刚刚通过无效字符,产生无效的XML。 11g抛出一个错误,这可能是更正确的行为,即使它在我的情况下很烦人。

我找到的唯一合理的解决方案是在源头修复内容。

答案 3 :(得分:0)

如果希望保留换行符,可以尝试如下操作:

select xmlelement("test", regexp_replace(test, '[^[:print:]|[:space:]]', '#')) from  
    (select '-   <- to keep line break after weird char
-' test from dual ) 
  • 替换所有^ =>不在集合中的字符(打印[:print:]或空格|[:space:]字符)