xml中的实体,例如 表示空格,如果xml文件中有这种数据,我用SAX方式的Characters()函数获得的数据都是基于unicode的,我把他们用WideCharToMultiByte方式转换未ANSI,发现 转换后的结果为“?”(英文问号),也就是说转换过程中实体丢失了!
该如何解决?请高手支招!我的代码如下:
=====================================
HRESULT STDMETHODCALLTYPE CMyContents::characters(
            /* [in] */ wchar_t __RPC_FAR *pwchChars,
            /* [in] */ int cchChars)
{
static WCHAR m_cElemValue[1048576]; //开辟1M的空间,用来存储从xml文件中读取出来的字段值。
cchChars = cchChars>1048575 ? 1048575 : cchChars;
    wcsncpy( m_cElemValue, pwchChars, cchChars ); m_cElemValue[cchChars] = 0;
BSTR bstr;
bstr = _bstr_t(m_cElemValue);
m_cElemValue[0] = 0;
DWORD cb,cwch = ::SysStringLen(bstr);//convert even embeded NULL char *szOut = NULL;
if(cb = ::WideCharToMultiByte(CP_ACP, 0, bstr, cwch + 1, NULL, 0, 0, 0))//CP_ACP
{
szOut = new char[cb];
if(szOut)
{
szOut[cb - 1]  = '\0';
//用下面的代码转换后就丢失了,不明白为什么!
if(!::WideCharToMultiByte(CP_ACP, 0, bstr, cwch + 1, szOut, cb, 0, 0))//CP_ACP
{
delete []szOut;//clean up if failed;
szOut = NULL;
}
}
}
m_sElemValue += szOut;
::SysFreeString(bstr);
delete []szOut;//clean up if failed;
szOut = NULL;
return S_OK;
}

解决方案 »

  1.   

    应该是可以解决的吧。
    记得以前这样用过:把xml文件(含有实体的引用)经过xslt转换后,除了xml的5个基础实体(‘>’、‘<’、‘&’、‘'’、‘"’),其它所有的实体就变成了正常的字符,只是不知道他们内部是如何实现的,找源码跟踪看看。
      

  2.   

    觉得还是那天说的问题if(cb = ::WideCharToMultiByte(CP_ACP, 0, pwchChars, cchChars, NULL, 0, 0, 0))//CP_ACPLPTSTR lpsz = CString::GetBuffer(cb + 1);
    if(!::WideCharToMultiByte(CP_ACP, 0, pwchChars, cchChars, lpsz, cb, 0, 0))//CP_ACPCString::ReleaseBuffer()
      

  3.   

    一直没有明白为什么你要转成BSTR,可能错误就出在这个地方
    另外上面提到使用GetBuffer,如果你使用+的话,需要注意Buffer中原有的字符
      

  4.   

    开辟1M的空间是没有必要的,因为pwchChars只保留当前行,就到回车地方的信息,一般来说应该不会很多,如果有很变态的XML文档,一行就写了1M多的话,仅pwchChars所占的内存就已经超过1M了,你再申请1M,赋值到CString又是1M,这样的内存占用量是无法承受的
      

  5.   

    snail对1M空间分析的很正确,当时徒省事,就这么写了,待会儿修改一下。
    另外,转换的问题还是没有解决。
      

  6.   

    经过进一步分析,发现也并不是上面的WideCharToMultiByte函数的调用错误,而是Microsoft的SAX接口内部有问题(或许是调用的时候需要设置什么参数?)。
    我在XML文件中添加了一些实体,并对实体事先进行了定义,发现:
    使用上面的SAX的Characters()接口,只能得到五个XML规范中定义的独有实体(&gt;&lt;&amp;&apos;&quot;一楼已经提到),对于任何其他的实体,无论是用代号的方式(例如:&nbsp;&Aacute;),还是编码的方式(例如:&#160;&#193;),characters()接口都不会报告争取的字符内码。对于前者--代号的方式,SAX直接过滤掉了;对于后者--编码的方式,则返回的值基本正确。
    下面是程序中的实例:
    A:“【】”中为xml文件的内容:
    【&#38;&#225;&amp;&Aacute;&gt;&#193;&lt;&nbsp;&apos;&#160;&quot;T】
       1     2    3     4      5   6     7    8    9     10     11  12 ->这里标注上面字符的索引。下面是经过MS SAX的Characters()接口返回的值:
    B:【&á&>á<'?"T】
      1234567890 ->这里标注上面字符的索引。
    xml中的实体与解析结果的对应关系是这样的:
    A索引   实体    B索引  字符  描述
    1 &#38;  1 & 正确转换
    2 &#225; 2 á 正确转换
    3 &amp; 3  无 正确转换
    4 &Aacute;无 无 实体丢失,应该是á,下面的a大写
    5 &gt; 4 > 正确转换
    6 &#193; 5 á 正确转换
    7 &lt; 6 < 正确转换
    8 &nbsp; 无 无 实体丢失
    9 &apos; 7 '  正确转换
    10 &#160; 8 ? 转换错误,应该为空格符号
    11 &quot; 9 " 正确转换
    12 T 0 T 正确转换因此,根据上面也可以总结出来,MS SAX的Characters接口本身存在问题,或者是我使用中存在配置问题。还没有查明白。
      

  7.   

    上面表格变乱了,重发:
    -----------------------------------
    A:“【】”中为xml文件的内容:
    【&#38;&#225;&amp;&Aacute;&gt;&#193;&lt;&nbsp;&apos;&#160;&quot;T】
       1     2    3      4     5    6    7    8    9     10    11   12 ->这里标注上面字符的索引。下面是经过MS SAX的Characters()接口返回的值:
    B:【&á&>á<'?"T】
      1234567890 ->这里标注上面字符的索引。
    xml中的实体与解析结果的对应关系是这样的:
    A索引 实体    B索引 字符 描述
    1    &#38;    1     &    正确转换
    2    &#225;   2     á    正确转换
    3    &amp;    3    无    正确转换
    4    &Aacute;无    无    实体丢失,应该是á,下面的a大写
    5    &gt;     4    >     正确转换
    6    &#193;   5    á     正确转换
    7    &lt;     6    <     正确转换
    8    &nbsp;   无   无    实体丢失
    9    &apos;   7    '     正确转换
    10   &#160;   8    ?     转换错误,应该为空格符号
    11   &quot;   9    "     正确转换
    12   T        0    T     正确转换因此,根据上面也可以总结出来,MS SAX的Characters接口本身存在问题,或者是我使用中存在配置问题。还没有查明白。