【原创】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>

posted @ 2010-11-24 16:12  天堂大鸟  阅读(2107)  评论(0编辑  收藏  举报