以往在C#或者Java里面,都有很好的DOM来支持读写XML文档,在C++里面也有相应的不少。而MSXML是Windows下最常用的一个组件,以COM组件单独发布出来称为一个WINDOWS组件的。
首先需要通过#import "msxml.dll"连链接MSXML的dll
然后通过CoCreateInstance来创建COM接口:
CComPtr<IXMLDOMDocument> pDoc;
CComPtr<IXMLDOMElement> elementRoot;
CComPtr<IXMLDOMNode> pNode;
CComPtr<IXMLDOMDocument> pElement;
VARIANT_BOOL isSuccessful;
VARIANT varValue;
hr = ::CoCreateInstance(CLSID_DOMDocument, 0, CLSCTX_INPROC, IID_IXMLDOMDocument, (void **)(&pDoc));
if(FAILD(hr))
{
_ASSERT(false):
return hr;
}
hr = pRequestDoc->loadXML(BSTR(wszXml), &isSuccessful);
if(FAILD(hr) || !isSuccessful)
{
_ASSERT(false):
return hr;
}
hr = elementRoot->selectSingleNode(L"/testnode", &pNode);
if(FAILD(hr) || !isSuccessful)
{
_ASSERT(false):
return hr;
}
pElement = pNode;
hr = pRequestElement->getAttribute(L"type", &varValue);
if (varValue.vt == VT_BSTR)
{
std::wstring wszTypeName = varValue.bstrVal;
std::wcout<<wszTypeName<<endl;
}
有趣的是这个VARIANT这个结构体。
typedef /* [wire_marshal] */ struct tagVARIANT VARIANT;
struct tagVARIANT
{
union
{
struct __tagVARIANT
{
VARTYPE vt;
WORD wReserved1;
WORD wReserved2;
WORD wReserved3;
union
{
LONGLONG llVal;
LONG lVal;
BYTE bVal;
SHORT iVal;
FLOAT fltVal;
DOUBLE dblVal;
VARIANT_BOOL boolVal;
_VARIANT_BOOL bool;
SCODE scode;
CY cyVal;
DATE date;
BSTR bstrVal;
IUnknown *punkVal;
IDispatch *pdispVal;
SAFEARRAY *parray;
BYTE *pbVal;
SHORT *piVal;
LONG *plVal;
LONGLONG *pllVal;
FLOAT *pfltVal;
DOUBLE *pdblVal;
VARIANT_BOOL *pboolVal;
_VARIANT_BOOL *pbool;
SCODE *pscode;
CY *pcyVal;
DATE *pdate;
BSTR *pbstrVal;
IUnknown **ppunkVal;
IDispatch **ppdispVal;
SAFEARRAY **pparray;
VARIANT *pvarVal;
PVOID byref;
CHAR cVal;
USHORT uiVal;
ULONG ulVal;
ULONGLONG ullVal;
INT intVal;
UINT uintVal;
DECIMAL *pdecVal;
CHAR *pcVal;
USHORT *puiVal;
ULONG *pulVal;
ULONGLONG *pullVal;
INT *pintVal;
UINT *puintVal;
struct __tagBRECORD
{
PVOID pvRecord;
IRecordInfo *pRecInfo;
} __VARIANT_NAME_4;
} __VARIANT_NAME_3;
} __VARIANT_NAME_2;
DECIMAL decVal;
} __VARIANT_NAME_1;
} ;
它把各种数据类型都封装到一个union,然后再加上vt一个来确定数据类型的type,还有wReserved1-wReserved3三个保留字段。这个结构体虽然简单,但是却在很多其他地方,特别是未知数据类型的变量参数传递的时候有很重要的方便作用。