eygle.com   eygle.com
eygle.com eygle
eygle.com  
 

« 我与牛君初相识-为《DB2数据库性能调整和优化》一书序 | Blog首页 | 分区表的维护 - ORA-14402 更新分区关键字列 »

xmldom.setCharset无效问题的解决
modb.pro

有朋友问到关于XMLDOM无法正确设置字符集的问题,也就是xmldom.setCharset无效的问题。
查询一下Metalink,参考Note:251011.1,这是Oracle的一个Bug,可以通过dbms_output来绕过这个问题。

在Oracle Databsae 10g中测试:
SQL> select * from v$version
  2  /

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Prod
PL/SQL Release 10.2.0.2.0 - Production
CORE    10.2.0.2.0      Production
TNS for Linux: Version 10.2.0.2.0 - Production
NLSRTL Version 10.2.0.2.0 - Production

效果如下,这是一个普遍性问题,在9i、10g中都存在:
SQL> create or replace procedure test_SETCHARSET
  2  is
  3  doc xmldom.DOMDocument;
  4  main_node xmldom.DOMNode;
  5  root_node xmldom.DOMNode;
  6 
  7  item_node xmldom.DOMNode;
  8  root_elmt xmldom.DOMElement;
  9  item_elmt xmldom.DOMElement;
10  item_text xmldom.DOMText;
11 
12 
13 
14  buffer_problem          varchar2(2000); 
15  buffer_root_node      varchar2(2000);
16  buffer_doc_header      varchar2(80);
17  buffer_doc            varchar2(2000);
18  reqRootNode xmldom.DOMNode; 
19 
20  BEGIN
21  --
22  -- the problem : 
23  --
24  dbms_output.put_line('=========== ');
25  dbms_output.put_line(' PROBLEM: setCharSet ISO-8859-1 has no effect' );
26 
27  doc := xmldom.newDOMDocument;
28  main_node := xmldom.makeNode(doc);
29  xmldom.setversion(doc,'1.0');
30  xmldom.setCharset(doc,'ISO-8859-1');
31  root_elmt := xmldom.createElement(doc, 'A');
32  root_node := xmldom.appendChild( main_node, xmldom.makeNode(root_elmt));
33 
34  item_elmt := xmldom.createElement(doc, 'B');
35  item_node := xmldom.appendChild(root_node, xmldom.makeNode(item_elmt));
36  -- chr (192) :    LATIN CAPITAL LETTER A WITH GRAVE in  ISO-8859-1
37  item_text := xmldom.createTextNode(doc, 'X' ||chr (192) ||'X');
38  item_node := xmldom.appendChild(item_node, xmldom.makeNode(item_text));
39 
40  xmldom.writetobuffer(doc, buffer_problem);
41  -- the final document here is encoded in UTF8
42  dbms_output.put_line(buffer_problem);
43  dbms_output.put_line(' ');
44  dbms_output.put_line('=========== ');
45 
46  --
47  -- workaround
48  --
49 
50  dbms_output.put_line(' WORKAROUND:' );
51  dbms_output.put_line(' '); 
52    buffer_doc_header := '<?xml version="1.0" encoding="ISO-8859-1"?>';
53    reqRootNode := xmldom.makeNode (xmldom.getDocumentElement(doc));
54   
55    xmldom.writetobuffer(reqRootNode, buffer_root_node);
56    buffer_root_node := convert (buffer_root_node,'WE8ISO8859P1','UTF8');
57    buffer_doc :=  buffer_doc_header || buffer_root_node;
58   
59  dbms_output.put_line(buffer_doc );
60  dbms_output.put_line('=========== ');
61  --
62 
63  xmldom.freeDocument(doc);
64 
65  END;
66  /

Procedure created.

SQL> set serveroutput on
SQL> exec test_setcharset
===========
PROBLEM: setCharSet ISO-8859-1 has no effect
<?xml version="1.0"?>
<A>
  <B>XX</B>
</A>


===========
WORKAROUND:
<?xml version="1.0" encoding="ISO-8859-1"?><A>
  <B>XX</B>
</A>


===========

PL/SQL procedure successfully completed.

测试用例来自Metalink,供参考!


历史上的今天...
    >> 2013-01-14文章:
    >> 2011-01-14文章:
    >> 2010-01-14文章:
    >> 2008-01-14文章:
    >> 2007-01-14文章:
           2006 中国ERP市场谁主沉浮?
    >> 2006-01-14文章:
    >> 2005-01-14文章:
           HRAY纳斯达克的IPO历程

By eygle on 2009-01-14 22:18 | Comments (1) | Advanced | 2155 |

1 Comment

仅供参考
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2791321000346652231

http://forums.oracle.com/forums/thread.jspa?threadID=990936&tstart=405


line 8 is different


SQL> list
1 declare
2 l_xml XMLDom.DomDocument;
3 l_mainNode xmldom.DOMNode;
4 l_xmltype xmltype;
5 begin
6 l_xml := xmldom.newDomDocument;
7 l_mainNode := xmldom.makeNode( l_xml );
8 dbms_xmldom.setVersion( l_xml, '1.0" encoding="UTF-8' );
9 dbms_xmldom.setCharset( l_xml, 'UTF-8' );
10 l_xmltype:= dbms_xmldom.getxmltype ( l_xml );
11 dbms_output.put_line ( l_xmltype.getStringVal( ) );
12* end;
SQL> /

PL/SQL procedure successfully completed.



CopyRight © 2004~2020 云和恩墨,成就未来!, All rights reserved.
数据恢复·紧急救援·性能优化 云和恩墨 24x7 热线电话:400-600-8755 业务咨询:010-59007017-7040 or 7037 业务合作: marketing@enmotech.com