2

我在 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() 甚至无法加载格式良好的 xml。我在代码中做错了什么。任何帮助是极大的赞赏。

谢谢JeeZ

4

3 回答 3

3

对于这个特定的问题,请参考Strings Passed to loadXML must be UTF-16 Encoded BSTRs

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

于 2010-08-12T14:29:58.707 回答
2

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

你可以很容易

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

这将正确处理内存。

至于它失败的原因——你可以向 DOMDocument 询问它的 parseError 对象 IXMLDOMParseError,然后从中获取原因——这可能会更清楚地说明真正的问题是什么。

于 2010-01-21T16:41:14.807 回答
0

我们用

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

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

于 2010-08-12T14:40:46.990 回答