No es realmente una pregunta porque ya he encontrado una solución. Me tomó mucho tiempo, es por eso que quiero explicarlo aquí.¿Cómo usar msxml con Visual Studio 2008 Express (sin clases ATL) sin volverse loco?
Msxml está basado en COM por lo que no es realmente fácil de usar en C++ incluso cuando tiene clases útiles para tratar problemas de asignación de memoria. Pero escribir un nuevo analizador XML sería mucho más difícil, así que quería usar msxml.
El problema:
pude encontrar suficientes ejemplos en el Internet para utilizar msxml con la ayuda de CComPtr
(puntero inteligente para no tener que llamar a Release() para cada IXMLDOMNode manualmente), CComBSTR
(para convertir cadenas de C++ al formato COM para cadenas) y CComVariant
. Estas 3 clases útiles son clases ATL y necesitan un #include <atlbase.h>
.
Problema: Visual Studio 2008 Express (la versión gratuita) no incluye ATL.
Solución:
Uso comutil.h
y comdef.h
, que incluyen algunas clases de ayuda simples:
_bstr_t
reemplaza más o menosCComBSTR
_variant_t
reemplaza más o menosCComVariant
_com_ptr_t
sustituye indirectamenteCComPtr
mediante el uso de_COM_SMARTPTR_TYPEDEF
ejemplo Pequeño:
#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();
}
VS2008 express no incluye ATL? eso apesta. > :( –