我正在尝试使用来自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数据库的生成文件中显示这些特定字符?
答案 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;