当dbms_xmldom.DOMDocument包含特殊字符时,如何正确地将该文档转换为CLOB

当dbms_xmldom.DOMDocument包含特殊字符时,如何正确地将该文档转换为CLOB,xml,oracle,plsql,Xml,Oracle,Plsql,考虑以下SQLFIDLE:,它承载以下PL/SQL函数: create or replace function GetSymbol return clob is v_domdocument dbms_xmldom.DOMDocument; v_root_node dbms_xmldom.DOMNode; v_root_child dbms_xmldom.DOMNode; v_text dbms_xmldom.DOMNode; v_xmltype x

考虑以下SQLFIDLE:,它承载以下PL/SQL函数:

create or replace function GetSymbol return clob is
  v_domdocument dbms_xmldom.DOMDocument;
  v_root_node   dbms_xmldom.DOMNode;
  v_root_child  dbms_xmldom.DOMNode;
  v_text        dbms_xmldom.DOMNode;
  v_xmltype     xmltype;
begin
  v_domdocument := dbms_xmldom.newDOMDocument;
  dbms_xmldom.setVersion(v_domdocument, '1.0" encoding="UTF-8');
  dbms_xmldom.setCharset(v_domdocument, 'UTF-8');
  v_root_node  := dbms_xmldom.makeNode(v_domdocument);
  v_root_child := dbms_xmldom.appendChild(v_root_node,
                                          dbms_xmldom.makeNode(dbms_xmldom.createElement(v_domdocument, 'root')));
  v_text       := dbms_xmldom.appendChild(v_root_child,
                                          dbms_xmldom.makeNode(dbms_xmldom.createTextNode(v_domdocument, NCHR(8364)))); -- Euro symbol
  v_xmltype    := dbms_xmldom.getxmltype(v_domdocument);
  return v_xmltype.getClobVal;
end;
如果执行以下SELECT语句:

select GetSymbol from dual;
…然后SQLFIDLE返回以下XML:

<?xml version="1.0" encoding="UTF-8"?> <root>€</root>
到目前为止还不错。但是,如果我在Oracle 11g数据库上尝试此操作,我会突然发现:

<?xml version="1.0" encoding="UTF-8"?> <root>¿</root>

也就是说,在NVARCHAR2-->dbms_xmldom.DOMNode/dbms_xmldom.DOMDocument-->xmltype-->CLOB之间的转换过程中,如上图所示,欧元符号会“转换”为一个倒问号


你知道这是怎么回事吗?我该怎么解决?我的目标是返回一个正确显示欧元符号的XML。

您的数据库字符集和国家字符集是什么,您使用的是哪个客户端,客户端和操作系统使用的是什么编码?这可能只是一个显示问题。(同样奇怪的是,您是否真的需要
NCHR(8364)
,而不是
unistr('\20ac')
,因为文档无论如何都是UTF-8?)通过从V$NLS_参数中选择,我可以收集到以下信息:NLS_CHARACTERSET=WE8DEC和NLS_NCHAR_CHARACTERSET=AL16UTF16。另外,我正在Windows 8上使用Allroundautomations的PL/SQL开发人员版本10.0.5.1710。要回答您的其他问题,我不需要
NCHR(8364)
。但是,
unistr('\20ac')
在我的客户端上产生相同的结果。我认为您仍然可以使用
unistr('\20ac')
生成符号。但问题是你的客户如何展示——或者说,它不能。(试着从dual中选择NCHR(8364),unistr('\20ac'),——我认为这两个字符都会显示相同的非字符;所以与XML无关。但是您可以
dump()
最后的CLOB来查看它真正的功能。)我不熟悉如何使用,但您可能需要更改PL/SQL Developer设置以使用Unicode或类似NLS_LANG的特定翻译。您的数据库字符集和国家字符集是什么,您使用的是哪个客户端,客户端和操作系统使用的编码是什么?这可能只是一个显示问题。(同样奇怪的是,您是否真的需要
NCHR(8364)
,而不是
unistr('\20ac')
,因为文档无论如何都是UTF-8?)通过从V$NLS_参数中选择,我可以收集到以下信息:NLS_CHARACTERSET=WE8DEC和NLS_NCHAR_CHARACTERSET=AL16UTF16。另外,我正在Windows 8上使用Allroundautomations的PL/SQL开发人员版本10.0.5.1710。要回答您的其他问题,我不需要
NCHR(8364)
。但是,
unistr('\20ac')
在我的客户端上产生相同的结果。我认为您仍然可以使用
unistr('\20ac')
生成符号。但问题是你的客户如何展示——或者说,它不能。(试着从dual中选择NCHR(8364),unistr('\20ac'),——我认为这两个字符都会显示相同的非字符;所以与XML无关。但是您可以
dump()
最后的CLOB来查看它真正的功能。)我不熟悉如何使用,但您可能需要更改PL/SQL开发人员设置以使用Unicode或类似于NLS_LANG的特定翻译。