如何在US7ASCII Oracle数据库的UTF8 xml文件中编写非ascii字符

时间:2014-10-24 01:43:33

标签: xml oracle utf-8 plsql non-ascii-characters

我正在尝试使用来自Oracle 9数据库(也应该在Oracle 11上运行)的数据编写以UTF-8编码的XML文件,该数据库设置为NLS_CHARACTERSET = US7ASCII,NLS_LANGUAGE = AMERICAN。 我使用XMLELEMENT和xmlattributes函数来构造clob,然后我从这个clob创建一个文件。

这是一个简单的例子:

declare
xmlval  clob;
begin
    SELECT XMLELEMENT( "Parent", 
      XMLELEMENT( "Address", xmlattributes( unistr( 'N°27' ) as "Street", unistr( '77800' ) as "PostCode", unistr( 'Paris' ) as "City" ) )
         ).extract('/*').getclobVal()
    INTO xmlval
    FROM DUAL;

    dbms_xslprocessor.clob2file( xmlval, 'DIRXMLTMP', 'file.xml', nls_charset_id('AL32UTF8') );
end;

数据库中的表可以包含几个非ascii字符,因为客户端使用的是Windows 1252字符代码集。

目前,我必须使用unistr函数,否则,当字段包含非ascii字符时,该过程会崩溃。

现在,此代码可以生成xml文件,但非ascii字符将替换为“?”字符:'N°27'变为'N?27'。

我尝试使用convert函数来修改字符串'N°27'或变量xmlval,例如:

convert( xmlval, 'WE8MSWIN1252', 'US7ASCII' )
convert( 'N°27', 'US7ASCII', 'WE8MSWIN1252' )

但是我仍然在结果文件中得到'N?27'。

是否可以在us7ascii数据库的生成文件中显示这些特定字符?

1 个答案:

答案 0 :(得分:2)

最后,我得到了一些解决方法:

1-创建一个函数来编码127以上的字符,作为表示由特定分隔符包围的相应十六进制代码的字符串:encodeSpecialChars('°') - > '#B0#'

2-创建解码编码字符串的函数:decodeSpecialChars('#B0#') - > '°'

3-通过过滤所有字段来创建XML clob

解码clob

5-转换clob的原始数据为UTF-8

6-使用utl_file和utl_raw包将数据保存到原始文件

declare
xmlval  clob;
begin
    SELECT XMLELEMENT( "Address", xmlattributes( encodeSpecialChars( 'N°27' ) as "Street", encodeSpecialChars( 'Frébault' ) as "City" )
         ).extract('/*').getclobVal()
    INTO xmlval
    FROM DUAL;

    -- <Address Street="N#B0#27" City="Fr#E9#bault"/>
    xmlval := decodeSpecialChars( xmlval );
    -- <Address Street="N°27" City="Frébault"/>     -- encoded in Windows-1252

    l_output := utl_file.fopen( 'DIRXMLTMP', 'fff.xml', 'w' );
    utl_file.PUT_RAW( l_output, UTL_RAW.convert( UTL_RAW.CAST_TO_RAW( xmlval ), 'FRENCH_FRANCE.AL32UTF8', 'FRENCH_FRANCE.WE8MSWIN1252' ) ); 
    utl_file.fclose( l_output );
end;