这不是一个真正的问题,因为我已经找到了解决方案。我花了很多时间,这就是为什么我想在这里解释一下。
Msxml 基于 COM,因此在 C++ 中使用它并不容易,即使您有有用的类来处理内存分配问题。但是编写一个新的 XML 解析器要困难得多,所以我想使用 msxml。
问题:
我能够在 Internet 上找到足够的示例来使用 msxml,借助CComPtr
(智能指针避免必须手动为每个 IXMLDOMNode 调用 Release())、CComBSTR
(将 C++ 字符串转换为字符串的 COM 格式)和CComVariant
. 这 3 个有用的类是 ATL 类,需要一个#include <atlbase.h>
.
问题:Visual Studio 2008 Express(免费版)不包括 ATL。
解决方案:
使用comutil.h
and comdef.h
,其中包括一些简单的辅助类:
_bstr_t
或多或少地替换CComBSTR
_variant_t
或多或少地替换CComVariant
_com_ptr_t
CComPtr
通过使用间接替换_COM_SMARTPTR_TYPEDEF
小例子:
#include <msxml.h>
#include <comdef.h>
#include <comutil.h>
// Define some smart pointers for MSXML
_COM_SMARTPTR_TYPEDEF(IXMLDOMDocument, __uuidof(IXMLDOMDocument)); // IXMLDOMDocumentPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMElement, __uuidof(IXMLDOMElement)); // IXMLDOMElementPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMNodeList, __uuidof(IXMLDOMNodeList)); // IXMLDOMNodeListPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMNamedNodeMap, __uuidof(IXMLDOMNamedNodeMap)); // IXMLDOMNamedNodeMapPtr
_COM_SMARTPTR_TYPEDEF(IXMLDOMNode, __uuidof(IXMLDOMNode)); // IXMLDOMNodePtr
void test_msxml()
{
// This program will use COM
CoInitializeEx(NULL, COINIT_MULTITHREADED);
{
// Create parser
IXMLDOMDocumentPtr pXMLDoc;
HRESULT hr = CoCreateInstance(__uuidof (DOMDocument), NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXMLDoc);
pXMLDoc->put_validateOnParse(VARIANT_FALSE);
pXMLDoc->put_resolveExternals(VARIANT_FALSE);
pXMLDoc->put_preserveWhiteSpace(VARIANT_FALSE);
// Open file
VARIANT_BOOL bLoadOk;
std::wstring sfilename = L"testfile.xml";
hr = pXMLDoc->load(_variant_t(sfilename.c_str()), &bLoadOk);
// Search for node <testtag>
IXMLDOMNodePtr pNode;
hr = pXMLDoc->selectSingleNode(_bstr_t(L"testtag"), &pNode);
// Read something
_bstr_t bstrText;
hr = pNode->get_text(bstrText.GetAddress());
std::string sSomething = bstrText;
}
// I'm finished with COM
// (Don't call before all IXMLDOMNodePtr are out of scope)
CoUninitialize();
}