c – 如何将msxml与Visual Studio 2008 Express(没有ATL类)一起使用而不会变得疯狂?

前端之家收集整理的这篇文章主要介绍了c – 如何将msxml与Visual Studio 2008 Express(没有ATL类)一起使用而不会变得疯狂?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这不是一个问题,因为我已经找到了解决方案.我花了很多时间,这就是我想在这里解释的原因.

Msxml基于COM,所以即使你有一些有用的类来处理内存分配问题,它也不是很容易在C中使用.但是编写一个新的XML解析器要困难得多,所以我想使用msxml.

问题:

我能够在互联网上找到足够的例子,在CComPtr的帮助下使用msxml(智能指针避免必须手动调用每个IXMLDOMNode的Release()),CComBSTR(将C字符串转换为字符串的COM格式)和CComVariant .这3个有用的类是ATL类,需要#include< atlbase.h>.

问题:Visual Studio 2008 Express(免费版)不包含ATL.

解:

使用comutil.h和comdef.h,其中包含一些简单的帮助器类:

> _bstr_t或多或少取代CComBSTR
> _variant_t或多或少取代CComVariant
> _com_ptr_t通过使用_COM_SMARTPTR_TYPEDEF间接替换CComPtr

小例子:

  1. #include <msxml.h>
  2. #include <comdef.h>
  3. #include <comutil.h>
  4.  
  5. // Define some smart pointers for MSXML
  6. _COM_SMARTPTR_TYPEDEF(IXMLDOMDocument,__uuidof(IXMLDOMDocument)); // IXMLDOMDocumentPtr
  7. _COM_SMARTPTR_TYPEDEF(IXMLDOMElement,__uuidof(IXMLDOMElement)); // IXMLDOMElementPtr
  8. _COM_SMARTPTR_TYPEDEF(IXMLDOMNodeList,__uuidof(IXMLDOMNodeList)); // IXMLDOMNodeListPtr
  9. _COM_SMARTPTR_TYPEDEF(IXMLDOMNamedNodeMap,__uuidof(IXMLDOMNamedNodeMap)); // IXMLDOMNamedNodeMapPtr
  10. _COM_SMARTPTR_TYPEDEF(IXMLDOMNode,__uuidof(IXMLDOMNode)); // IXMLDOMNodePtr
  11.  
  12. void test_msxml()
  13. {
  14. // This program will use COM
  15. CoInitializeEx(NULL,COINIT_MULTITHREADED);
  16.  
  17. {
  18. // Create parser
  19. IXMLDOMDocumentPtr pXMLDoc;
  20. HRESULT hr = CoCreateInstance(__uuidof (DOMDocument),NULL,CLSCTX_INPROC_SERVER,IID_IXMLDOMDocument,(void**)&pXMLDoc);
  21. pXMLDoc->put_validateOnParse(VARIANT_FALSE);
  22. pXMLDoc->put_resolveExternals(VARIANT_FALSE);
  23. pXMLDoc->put_preserveWhiteSpace(VARIANT_FALSE);
  24.  
  25. // Open file
  26. VARIANT_BOOL bLoadOk;
  27. std::wstring sfilename = L"testfile.xml";
  28. hr = pXMLDoc->load(_variant_t(sfilename.c_str()),&bLoadOk);
  29.  
  30. // Search for node <testtag>
  31. IXMLDOMNodePtr pNode;
  32. hr = pXMLDoc->selectSingleNode(_bstr_t(L"testtag"),&pNode);
  33.  
  34. // Read something
  35. _bstr_t bstrText;
  36. hr = pNode->get_text(bstrText.GetAddress());
  37. std::string sSomething = bstrText;
  38. }
  39.  
  40. // I'm finished with COM
  41. // (Don't call before all IXMLDOMNodePtr are out of scope)
  42. CoUninitialize();
  43. }

解决方法

也许尝试使用#import语句.

我在一个VS6项目中使用过它,我做了类似的事情(仅用于说明目的;这对我有用,但我并不认为是错误证明):

  1. #import "msxml6.dll"
  2.  
  3. ...
  4.  
  5. MSXML2::IXMLDOMDocument2Ptr pdoc;
  6. HRESULT hr = pdoc.CreateInstance(__uuidof(MSXML2::DOMDocument60));
  7. if (!SUCCEEDED(hr)) return hr;
  8.  
  9. MSXML2::IXMLDOMDocument2Ptr pschema;
  10. HRESULT hr = pschema.CreateInstance(__uuidof(MSXML2::DOMDocument60));
  11. if (!SUCCEEDED(hr)) return hr;
  12.  
  13. pschema->async=VARIANT_FALSE;
  14. VARIANT_BOOL b;
  15. b = pschema->loadXML(_bstr_t( /* your schema XML here */ ));
  16.  
  17. MSXML2::IXMLDOMSchemaCollection2Ptr pSchemaCache;
  18. hr = pSchemaCache.CreateInstance(__uuidof(MSXML2::XMLSchemaCache60));
  19. if (!SUCCEEDED(hr)) return hr;
  20.  
  21. _variant_t vp=pschema.GetInterfacePtr();
  22. pSchemaCache->add(_bstr_t( /* your namespace here */ ),vp);
  23.  
  24. pdoc->async=VARIANT_FALSE;
  25. pdoc->schemas = pSchemaCache.GetInterfacePtr();
  26. pdoc->validateOnParse=VARIANT_TRUE;
  27. if (how == e_filename)
  28. b = pdoc->load(v);
  29. else
  30. b = pdoc->loadXML(bxmldoc);
  31.  
  32. pXMLError = pdoc->parseError;
  33. if (pXMLError->errorCode != 0)
  34. return E_FAIL; // an unhelpful return code,sigh....

猜你在找的C&C++相关文章