{
// Style for normalization
char pszStyle[]=
"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\
<xsl:output method=\"xml\" indent=\"yes\" encoding=\"UTF-8\" standalone=\"yes\"/>\
<xsl:template match=\"@* | node()\">\
<xsl:copy>\
<xsl:apply-templates select=\"@* | node()\"/>\
</xsl:copy>\
</xsl:template>\
</xsl:stylesheet>";
// Create a style dom document
MSXML2::IXMLDOMDocument2Ptr pStyle=NULL;
pStyle.CreateInstance( __uuidof( MSXML2::DOMDocument26) );
BSTR styleStr = _bstr_t(pszStyle);
pStyle->loadXML(styleStr);//这里用loadXML的话由于使用BSTR类型(默认为UTF-16编码),加载进的XML将被自动转//换为UTF-16编码格式
// Create a new doc for return
MSXML2::IXMLDOMDocumentPtr pNew=NULL;
pNew.CreateInstance( __uuidof( MSXML2::DOMDocument26) );
// Transform
pNew->loadXML(pXMLDocOld->transformNode(pStyle));//transformNode将返回BSTR类型数据
//这里用loadXML的话由于使用BSTR类型(默认为UTF-16编码),加载进的XML将被自动转//换为UTF-16编码格式,因此导致输出的文件只能是UTF-16编码文件,破坏了原有的文件编码
return pNew;
}
对上述问题,解释与解决方案如下:
MSXML DOM 错误
两个常见的错误从 XML 文档对象模型 (DOM) 接口方法返回的是:- 指定没有编码、 找到没有字节顺序标记开头的 XML 文件和数据中包含特殊字符 encoded in UTF-16 format (such as Swedish character å, or 0xE5) rather than the default UTF-8 (0xC3 0xA5) format.
- 指定的编码与 XML 数据的实际编码不匹配。
使用 MSXML 分析器版本 2.5,2.5 SP1 和 2.6, loadXML方法的IXMLDOMDocument只能加载 utf-16 或 ucs-2 编码数据。任何尝试加载 XML 数据使用另一种编码格式导致以下错误:
hr = pXMLDoc->loadXML("<?xml version=\"1.0\" encoding=\"UTF-8\"?><tag1>Abcdef</tag1>");
XSL 或 XSLT 文件的 XML 编码的信息,如下所示指定在其中调用IXMLDOMNode接口的transformNode方法时,您还可能收到以下错误:
<xsl:output method="xml" encoding="UTF-8" />
因此上述代码应修改为:
MSXML2::IXMLDOMDocument2Ptr CXMLDOMFile::XMLNormalize( MSXML2::IXMLDOMDocument2Ptr pXMLDocOld)
{
// Style for normalization
char pszStyle[]=
"<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\" encoding=\"utf-8\">\
<xsl:output method=\"xml\" encoding=\"utf-8\" indent=\"yes\" />\//指定使用UTF-8编码存储xml文件
<xsl:template match=\"@* | node()\">\
<xsl:copy>\
<xsl:apply-templates select=\"@* | node()\"/>\
</xsl:copy>\
</xsl:template>\
</xsl:stylesheet>";
// Create a style dom document
MSXML2::IXMLDOMDocument2Ptr pXMLStyle=NULL;
pXMLStyle.CreateInstance( __uuidof( MSXML2::DOMDocument26) );
BSTR styleStr = _bstr_t(pszStyle);
pXMLStyle->loadXML(styleStr);
// Create a new doc for return
MSXML2::IXMLDOMDocumentPtr pNew=NULL;
pNew.CreateInstance( __uuidof( MSXML2::DOMDocument26) );
// Transform
IDispatch *pDisp = NULL;
pNew->QueryInterface(IID_IDispatch, (void**)&pDisp);
VARIANT varDisp;
VariantInit(&varDisp);
V_VT(&varDisp) = VT_DISPATCH;
V_DISPATCH(&varDisp) = pDisp;
pDisp = NULL;
pXMLDocOld->transformNodeToObject(pXMLStyle,varDisp);
//这样修改之后,最终的pNew指向的XML文件格式才符合上述xsl中指定的utf-8编码
return pNew;
}
参考资料:http://msdn.microsoft.com/en-us/library/ms757821(v=vs.85).aspx