【原创】C++利用IXMLDOM解析XML文件。
项目是在wince平台下做的,但是解析过程和代码却别不大,贴出代码,留做备份。
// TestIXML.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <comutil.h> #include <stdlib.h> #include <stdio.h> #include <MsXml2.h> #pragma comment(lib, "ole32.lib") #pragma comment(lib, "oleaut32.lib") void TestXML(); void TestSound(); #define TIROSLIB_DBG_FILE "\\Test_Pro.log" void dbgprintf(const char *str, ...) { va_list ap; FILE *fh = NULL; if(fh = fopen(TIROSLIB_DBG_FILE, "a")) { va_start(ap, str); vfprintf(fh, str, ap); fprintf(fh, "\n"); va_end(ap); fclose(fh); fh = NULL; } } typedef struct _weather_info_node { char szDate[32]; char szCondition[5]; char szWind[32]; float fLowTemp; float fHighTemp; int nReserved; struct _weather_info_node *lpNext; }weather_info_node; weather_info_node *m_lpWeatherNode = NULL; weather_info_node *NewWeatherNode() { weather_info_node *newNode = (weather_info_node *)malloc(sizeof(weather_info_node)); memset(newNode, 0, sizeof(weather_info_node)); newNode->lpNext = NULL; return newNode; } void DestoryWeatherList(weather_info_node **weatherList) { weather_info_node *DElem, *next; DElem = *weatherList; while(DElem) { next = DElem->lpNext; free(DElem); DElem = next; } *weatherList = NULL; } BOOL ParseWeatherXml(const char *lpXmlPath) { //xml节点名的枚举 enum node_Names{xml_day, xml_low, xml_high, xml_condition, xml_wind}; IXMLDOMDocument *pXMLDocument= NULL; IXMLDOMNode *pNode = NULL; IXMLDOMNodeList *pNodeList = NULL; IXMLDOMNodeList *pChildNodeList = NULL; IXMLDOMParseError * pObjError = NULL; IXMLDOMNamedNodeMap *pNodeMap = NULL; //DOMNodeType nodeType; VARIANT vXmlPath; VARIANT vValue; VARIANT_BOOL vbStatus; BSTR bstr = NULL; long lLength = 0; weather_info_node *lpTemp = NULL; int nLen = strlen(lpXmlPath) + 1; int nwLen = MultiByteToWideChar(CP_ACP, 0, lpXmlPath, nLen, NULL, 0); TCHAR lpSzXmlPath[256]; MultiByteToWideChar(CP_ACP, 0, lpXmlPath, nLen, lpSzXmlPath, nwLen); VariantInit(&vXmlPath); V_BSTR(&vXmlPath) = SysAllocString(lpSzXmlPath); V_VT(&vXmlPath) = VT_BSTR; CoInitializeEx(NULL, COINIT_MULTITHREADED); HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, (void**)&pXMLDocument); hr = pXMLDocument->put_async(VARIANT_FALSE); if (FAILED(hr)) { printf("Failed to set async property\n"); } hr = pXMLDocument->put_validateOnParse(VARIANT_FALSE); if (FAILED(hr)) { printf("Failed to set validateOnParse\n"); } hr = pXMLDocument->put_resolveExternals(VARIANT_FALSE); if (FAILED(hr)) { printf("Failed to disable resolving externals.\n"); } hr = pXMLDocument->load(vXmlPath, &vbStatus); if (vbStatus != VARIANT_TRUE) { hr = pXMLDocument->get_parseError(&pObjError); hr = pObjError->get_reason(&bstr); printf("Failed to load DOM from books.xml. %S\n",bstr); } hr = pXMLDocument->get_xml(&bstr); if(FAILED(hr)) { printf("xml 的内容:\n%S\n", bstr); SysFreeString(bstr); } hr = pXMLDocument->selectSingleNode(L"//weather", &pNode); //hr = pNode->get_nodeName(&bstr); hr = pNode->get_childNodes(&pNodeList); hr = pNodeList->get_length(&lLength); for (int nIndex = 0; nIndex != lLength; ++nIndex) { if (0 == nIndex) { m_lpWeatherNode = NewWeatherNode(); lpTemp = m_lpWeatherNode; } else { lpTemp->lpNext = NewWeatherNode(); lpTemp = lpTemp->lpNext; } hr = pNodeList->get_item(nIndex, &pNode); hr = pNode->get_childNodes(&pChildNodeList); long lChildLength = 0; hr = pChildNodeList->get_length(&lChildLength); for (int nChildIndex = 0; nChildIndex != lChildLength; ++nChildIndex) { //hr = pNode->get_nodeName(&bstr); switch(nChildIndex) { case xml_day: hr = pChildNodeList->get_item(nChildIndex, &pNode); hr = pNode->get_attributes(&pNodeMap); hr = pNodeMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&vValue); memcpy(lpTemp->szDate, (char *)(_bstr_t)vValue.bstrVal, strlen((char *)(_bstr_t)vValue.bstrVal)); break; case xml_low: hr = pChildNodeList->get_item(nChildIndex, &pNode); hr = pNode->get_attributes(&pNodeMap); hr = pNodeMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&vValue); lpTemp->fLowTemp = atof((char *)(_bstr_t)vValue.bstrVal); break; case xml_high: hr = pChildNodeList->get_item(nChildIndex, &pNode); hr = pNode->get_attributes(&pNodeMap); hr = pNodeMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&vValue); lpTemp->fHighTemp = atof((char *)(_bstr_t)vValue.bstrVal); break; case xml_condition: hr = pChildNodeList->get_item(nChildIndex, &pNode); hr = pNode->get_attributes(&pNodeMap); hr = pNodeMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&vValue); memcpy(lpTemp->szCondition, (char *)(_bstr_t)vValue.bstrVal, strlen((char *)(_bstr_t)vValue.bstrVal)); break; case xml_wind: hr = pChildNodeList->get_item(nChildIndex, &pNode); hr = pNode->get_attributes(&pNodeMap); hr = pNodeMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&vValue); memcpy(lpTemp->szWind, (char *)(_bstr_t)vValue.bstrVal, strlen((char *)(_bstr_t)vValue.bstrVal)); break; default: break; } } } pChildNodeList->Release(); pNodeMap->Release(); pNodeList->Release(); pNode->Release(); pXMLDocument->Release(); /* hr = pNodeList->get_item(3,&pNode); hr = pNode->get_attributes(&pMap); hr = pMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&vValue); */ return TRUE; } void TestMyXml() { char *lpTempPath = "\\Storage Card\\WeatherXML20101122150441.txt"; ParseWeatherXml(lpTempPath); while(m_lpWeatherNode != NULL) { dbgprintf("Date = %s,Low = %f, High = %f, Condition = %s, Wind = %s", m_lpWeatherNode->szDate, m_lpWeatherNode->fLowTemp, m_lpWeatherNode->fHighTemp, m_lpWeatherNode->szCondition, m_lpWeatherNode->szWind); m_lpWeatherNode = m_lpWeatherNode->lpNext; } } int _tmain(int argc, _TCHAR* argv[]) { TestMyXml(); //TestXML(); return 0; } void TestXML() { IXMLDOMDocument *pXMLDocument= NULL; IXMLDOMNode *pNode = NULL; IXMLDOMNodeList *pNodeList = NULL; IXMLDOMParseError * pObjError = NULL; DOMNodeType nodeType; IXMLDOMNamedNodeMap *pMap = NULL; VARIANT v1; VARIANT variantvalue; VARIANT_BOOL status; BSTR bstr = NULL; VariantInit(&v1); V_BSTR(&v1) = SysAllocString(L"D:\\WeatherXML20101122150441.txt"); V_VT(&v1) = VT_BSTR; // 首先必须调用CoInitialize CoInitializeEx(NULL, COINIT_MULTITHREADED); // 创建一msxml 文档实例,返回IXMLDOMDocument2接口。 HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, (void**)&pXMLDocument); hr = pXMLDocument->put_async(VARIANT_FALSE); if (FAILED(hr)) { printf("Failed to set async property\n"); //goto clean; } hr = pXMLDocument->put_validateOnParse(VARIANT_FALSE); if (FAILED(hr)) { printf("Failed to set validateOnParse\n"); //goto clean; } hr = pXMLDocument->put_resolveExternals(VARIANT_FALSE); if (FAILED(hr)) { printf("Failed to disable resolving externals.\n"); //goto clean; } hr = pXMLDocument->load(v1, &status); if (status!=VARIANT_TRUE) { hr = pXMLDocument->get_parseError(&pObjError); hr = pObjError->get_reason(&bstr); printf("Failed to load DOM from books.xml. %S\n",bstr); //goto clean; } hr = pXMLDocument->get_xml(&bstr); printf("foo.xml 的内容:\n%S\n", bstr); SysFreeString(bstr); hr = pXMLDocument->selectSingleNode(L"//fc", &pNode); hr = pNode->get_nodeName(&bstr); hr = pNode->get_childNodes(&pNodeList); long length; hr = pNodeList->get_length(&length); hr = pNodeList->get_item(3,&pNode); hr = pNode->get_attributes(&pMap); hr = pMap->get_item(0, &pNode); hr = pNode->get_nodeTypedValue(&variantvalue); //hr = pNode->get_childNodes(&pNodeList); //hr = pNodeList->get_item(0, &pNode); //hr = pNode->get_nodeType(&nodeType); //hr = pNode->get_nodeValue(&variantvalue); //hr = pNode->get_dataType(&variantvalue); // hr = pNode->get_xml(&bstr); //hr = pNode->get_nodeType(&nodeType); // variantvalue.vt = nodeType; // hr = pNode->get_dataType(&variantvalue); // hr = pNode->get_nodeValue(&variantvalue); //hr = pNode->get_nodeTypedValue(&variantvalue); // hr = pNode->get_ // if (FAILED(hr)) { // hr = pXMLDocument->get_parseError(&pObjError); // hr = pObjError->get_reason(&bstr); // printf("Failed to load DOM from books.xml. %S\n",bstr); // //goto clean; // } //hr = pNode->get_nodeName(&bstr); //DOMNodeType nodeType; //得到节点类型 //pNode->get_nodeType(&nodeType); //节点名称 // // BSTR nodeName; // // hr = pNode->get_nodeName(&nodeName); // // char *cNodeName = (char *)nodeName; //cNodeName = ConvertBSTRToString(nodeName); //strName=(char *)pNode->GetnodeName(); //节点属性,放在链表中 // MSXML2::IXMLDOMNamedNodeMapPtr pAttrMap=NULL; // MSXML2::IXMLDOMNodePtr pAttrItem; // _variant_t variantvalue; // pNode->get_attributes(&pAttrMap); // // long count; // count=pAttrMap->get_length(&count); // // pAttrMap->get_item(0,&pAttrItem); // //取得节点的值 // pAttrItem->get_nodeTypedvalue(&variantvalue); // m_strId=(char *)(_bstr_t)variantvalue; // // UpdateData(FALSE); //hr = pXMLDocument->getProperty(L"<day data/>", &v2); //hr = pXMLDocument->save(v1); //pXMLDocument->Release(); CoUninitialize(); }
xml文件:
<weather pd="2010-11-22 08:00:00" xmlns="http://www.xxx.com"> <fc> <day data="2010-11-22 08:00:00"/> <low data="-2.0"/> <high data="9.0"/> <condition data="晴"/> <wind data="静风、小于3级"/> <indexes> <index type="3" data="6"/> <index type="4" data="6"/> <index type="1" data="1"/> <index type="2" data="2"/> </indexes> </fc> <fc> <day data="2010-11-23 08:00:00"/> <low data="1.0"/> <high data="9.0"/> <condition data="阴"/> <wind data="静风、小于3级"/> </fc> <fc> <day data="2010-11-24 08:00:00"/> <low data="-4.0"/> <high data="6.0"/> <condition data="晴"/> <wind data="北风转静风、3级转小于3级"/> </fc> </weather>