2010-01-21 157 views
2

我已經寫了一個封裝在C++的MSXML的頂部。加載方法如下所示。 代碼的問題是它有時無法加載格式良好的XML。MSXML的loadXML無法載入,即使格式良好的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。我在代碼中做了什麼錯誤。任何幫助是極大的讚賞。

感謝老天

+0

與您的問題不完全相關:我嘗試編寫一個MSXML封裝並最終放棄,並在碰到與此類似的問題後直接使用MSXML。 – 2010-08-12 14:38:41

回答

3

對於此特定問題,請參閱Strings Passed to loadXML must be UTF-16 Encoded BSTRs。總的來說,xml解析器並不是專門爲內存字符串解析而設計的,例如, loadXML不識別BOM,並且對編碼有限制。相反,xml解析器是爲具有編碼檢測的字節數組形式而設計的,這對於標準解析器來說是至關重要的。爲了更好地利用MSXML,請考慮從IStream或Win32文件加載。

2

我不是A2BSTR的粉絲 - 至少是你泄漏內存作爲返回BSTR是永遠不會被釋放。

,你可以很容易地

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

這將妥善處理內存。

至於爲什麼它失敗 - 您可以要求DOMDocument的parseError對象IXMLDOMParseError,然後從中獲取原因 - 這可能會揭示真正的問題。

+0

感謝Ruddy的啓發,我不知道A2BSTR導致內存泄漏,從現在開始將使用CComBSTR。 會照你所說的去做,並試圖找出原因。 – JeeZ 2010-01-22 12:30:12

0

我們使用

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

分別加載文件和原始XML。

相關問題