MSXML的loadXML无法加载即使是格式良好的xml

时间:2010-01-21 14:09:55

标签: c++ msxml

我在c ++中用MSXML编写了一个包装器。加载方法如下所示。 代码的问题是它有时无法加载格式良好的XML。

在将xml作为字符串传递之前,我会对xmlns进行字符串搜索,并将所有出现的xmlns替换为xmlns:dns。  在下面的代码中,我删除了bom字符。然后我尝试使用MSXML loadXML方法加载。如果加载成功,我设置名称空间,如代码所示。

 Class XmlDocument{

        MSXML2::IXMLDOMDocument2Ptr spXMLDOM;
         ....
    }
  

// XmlDocument方法

void XmlDocument::Initialize()
    {

    CoInitialize(NULL);
    HRESULT hr = spXMLDOM.CreateInstance(__uuidof(MSXML2::DOMDocument60));
    if ( FAILED(hr) ) 
    {

        throw "Unable to create MSXML:: DOMDocument object";
    }

}
  

bool XmlDocument::LoadXml(const char* xmltext)
    {

        if(spXMLDOM != NULL)
        {

            char BOM[3] = {0xEF,0xBB,0xBF};
            //detect unicode BOM character
            if(strncmp(xmltext,BOM,sizeof(BOM)) == 0)
            {
                xmltext += 3;
            }

            VARIANT_BOOL bSuccess = spXMLDOM->loadXML(A2BSTR(xmltext));
            if ( bSuccess == VARIANT_TRUE) 
            {
                spXMLDOM->setProperty("SelectionNamespaces","xmlns:dns=\"http://www.w3.org/2005/Atom\"");

                return true;
            }
        }
        return false;

    }

我试图调试仍然无法理解为什么有时loadXML()无法加载即使是格式良好的xmls。我在代码中做错了什么。非常感谢任何帮助。

由于 哎呀

3 个答案:

答案 0 :(得分:3)

有关此特定问题,请参阅Strings Passed to loadXML must be UTF-16 Encoded BSTRs

总的来说,xml解析器不是为内存字符串解析而设计的,例如: loadXML无法识别BOM,并且对编码有限制。相反,xml解析器是为具有编码检测的字节数组形式设计的,这对于标准解析器至关重要。要更好地利用MSXML,请考虑从IStream或Win32文件加载。

答案 1 :(得分:2)

我不是A2BSTR的粉丝 - 至少你是在泄漏内存,因为返回的BSTR永远不会被释放。

你可以轻松地

      VARIANT_BOOL bSuccess = spXMLDOM->loadXML(CComBSTR(xmltext));

这将正确处理内存。

至于它失败的原因 - 您可以向DOMDocument询问其parseError对象IXMLDOMParseError,然后从中获取原因 - 这可能会更清楚地了解真正的问题。

答案 2 :(得分:0)

我们使用

hr = m_pXMLDoc->load(_variant_t(xml_file.c_str()), &varStatus);
hr = m_pXMLDoc->loadXML(_bstr_t(xml_doc.c_str()), &varStatus);

分别用于加载文件和原始xml。