MFC--显示HTTP获取到XML的列表信息

声明:本文是我项目过程中的一个小小的Demo,里面涉及到的知识是使用HTTP获取XML数据,然后使用tinyxml库解析获取到的XML数据。使用STL的Vector保存列表信息。最后使用List Control显示列表信息。

效果图:

MFC--显示HTTP获取到XML的列表信息_第1张图片


1.构造保存列表信息的类(结构体也可以)BuildingInfo

#pragma once
class BuildingInfo
{
public:
	BuildingInfo(void);
	~BuildingInfo(void);

	inline CString getBuildingId()
	{
		return m_buildingid;
	}

	inline CString getBuildingName()
	{
		return m_buildingname;
	}

	inline CString getFloorCount()
	{
		return m_floorcount;
	}

	inline void setBuildingId(CString &buildingid)
	{
		m_buildingid = buildingid;
	}

	inline void setBuildingName(CString &buildingname)
	{
		m_buildingname = buildingname;
	}

	inline void setFloorCount(CString &floorcount)
	{
		m_floorcount = floorcount;
	}

private:
	CString m_buildingid; // 楼栋Id
	CString m_buildingname; // 楼栋名称
	CString m_floorcount; // 楼栋楼层数
};
对应的CPP文件
#include "StdAfx.h"
#include "BuildingInfo.h"


BuildingInfo::BuildingInfo(void)
{
}


BuildingInfo::~BuildingInfo(void)
{
}

2.HTTP获取XML数据(不一定就是xml)CHttpClient

#include "StdAfx.h"
#include "HttpClient.h"
//#include   "emailsenderv2.h"
#ifdef   _DEBUG   
#undef   THIS_FILE   
static   char   THIS_FILE[]=__FILE__;   
#define   new   DEBUG_NEW   
#endif

CHttpClient::CHttpClient()
{

}

CHttpClient::~CHttpClient()
{

}

CString   CHttpClient::doGet(CString   href)
{
	CString   httpsource =_T("");
	CInternetSession   session1(NULL,0);
	CHttpFile*   pHTTPFile=NULL;

	try{
		pHTTPFile=(CHttpFile*)session1.OpenURL(href);
		//session1.
	}catch(CInternetException){
		pHTTPFile=NULL;
	}

	if(pHTTPFile)
	{
		CString   text;
		for(int   i=0;pHTTPFile->ReadString(text);i++)
		{
			//afxDump << "text:"<<text.GetBuffer()<<"\r\n";
			httpsource += text;// + _T("rn");
		}
		pHTTPFile->Close();
		delete   pHTTPFile;
	}else{

	}
	return   httpsource;
}

CString   CHttpClient::doPost(CString   href)
{
	CString   httpsource  = _T("");
	CInternetSession   session1;
	CHttpConnection*   conn1=NULL;
	CHttpFile*   pFile   =   NULL;
	CString   strServerName;
	CString   strObject;
	INTERNET_PORT   nPort;
	DWORD   dwServiceType;
	AfxParseURL((LPCTSTR)href,dwServiceType,   strServerName,   strObject,   nPort);
	DWORD   retcode;
	char*   outBuff = (char*)CONTENT.GetBuffer(1000);
	try
	{
		conn1   =   session1.GetHttpConnection(strServerName,nPort);
		pFile   =   conn1->OpenRequest(0,strObject.GetBuffer(),NULL,1,NULL,	_T("HTTP/1.1"),
			INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_AUTO_REDIRECT);
		pFile->AddRequestHeaders(_T("Content-Type:   application/x-www-form-urlencoded"));
		pFile   ->   AddRequestHeaders(_T("Accept:   */*"));
		pFile   ->   SendRequest(NULL,0,outBuff,strlen(outBuff)+1);
		pFile   ->   QueryInfoStatusCode(retcode);
	}
	catch   (CInternetException   *   e){};
	if(pFile)
	{
		CString   text;
		for(int   i=0;pFile->ReadString(text);i++)
		{
			httpsource +=  text;
		}
		pFile->Close();
	}else
	{

	}
	return   httpsource;
	delete   pFile;
	delete   conn1;
	session1.Close();
}

void   CHttpClient::addParam(CString   name,   CString   value)
{
	names.AddTail((LPCTSTR)name);
	values.AddTail((LPCTSTR)value);
	CString   eq=_T("=");
	CString   an=_T("&");
	CONTENT=CONTENT+name+eq+value+an;
	CL=CONTENT.GetLength();
}

bool CHttpClient::download(const CString &strFileURLInServer, const CString &strFileLocalFullPath, HWND hWnd)
{
	ASSERT(strFileURLInServer != "");
	ASSERT(strFileLocalFullPath != "");
	CInternetSession session;
	CHttpConnection* pHttpConnection = NULL;
	CHttpFile* pHttpFile = NULL;
	CString strServer, strObject;
	INTERNET_PORT wPort;

	DWORD dwType;
	const int nTimeOut = 2000;
	session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, nTimeOut); //重试之间的等待延时
	session.SetOption(INTERNET_OPTION_CONNECT_RETRIES, 1);   //重试次数
	char* pszBuffer = NULL;  

	try
	{
		AfxParseURL(strFileURLInServer, dwType, strServer, strObject, wPort);
		pHttpConnection = session.GetHttpConnection(strServer, wPort);
		pHttpFile = pHttpConnection->OpenRequest(CHttpConnection::HTTP_VERB_GET, strObject);
		if(pHttpFile->SendRequest() == FALSE)
			return false;
		DWORD dwStateCode;

		pHttpFile->QueryInfoStatusCode(dwStateCode);
		if(dwStateCode == HTTP_STATUS_OK)
		{
			HANDLE hFile = CreateFile(strFileLocalFullPath, GENERIC_WRITE,
				FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
				NULL);  //创建本地文件
			if(hFile == INVALID_HANDLE_VALUE)
			{
				int error = GetLastError(); // 错误码 5 拒绝访问,没有访问目录的权限
				pHttpFile->Close();
				pHttpConnection->Close();
				session.Close();
				return false;
			}

			char szInfoBuffer[1000];  //返回消息
			DWORD dwFileSize = 0;   //文件长度
			DWORD dwInfoBufferSize = sizeof(szInfoBuffer);
			BOOL bResult = FALSE;
			CString str;
			int pos;
			//bResult = pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, 
			//	(void*)&szInfoBuffer, &dwInfoBufferSize,NULL);
			bResult = pHttpFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, str);
			WideCharToMultiByte(0,0,str,-1,szInfoBuffer,64,0,0); // 宽字节转多字节
			//dwFileSize = atoi(str.GetString());
			dwFileSize = atoi(szInfoBuffer);
			const int BUFFER_LENGTH = 1024 * 10;
			pszBuffer = new char[BUFFER_LENGTH];  //读取文件的缓冲
			DWORD dwWrite, dwTotalWrite;
			dwWrite = dwTotalWrite = 0;
			UINT nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH); //读取服务器上数据
			while(nRead > 0)
			{
				WriteFile(hFile, pszBuffer, nRead, &dwWrite, NULL);  //写到本地文件
				dwTotalWrite += dwWrite;
				nRead = pHttpFile->Read(pszBuffer, BUFFER_LENGTH);
				pos = 100 * dwTotalWrite / dwFileSize;
				bResult = PostMessage(hWnd, WM_VERSION_UPDATE, (WPARAM)TRUE, (LPARAM)&pos);
			}

			delete[]pszBuffer;
			pszBuffer = NULL;
			CloseHandle(hFile);
		}
		else
		{
			delete[]pszBuffer;
			pszBuffer = NULL;
			if(pHttpFile != NULL)
			{
				pHttpFile->Close();
				delete pHttpFile;
				pHttpFile = NULL;
			}
			if(pHttpConnection != NULL)
			{
				pHttpConnection->Close();
				delete pHttpConnection;
				pHttpConnection = NULL;
			}
			session.Close();
			return false;
		}
	}
	catch(...)
	{
		delete[]pszBuffer;
		pszBuffer = NULL;
		if(pHttpFile != NULL)
		{
			pHttpFile->Close();
			delete pHttpFile;
			pHttpFile = NULL;
		}
		if(pHttpConnection != NULL)
		{
			pHttpConnection->Close();
			delete pHttpConnection;
			pHttpConnection = NULL;
		}
		session.Close();
		return false;
	}

	if(pHttpFile != NULL)
		pHttpFile->Close();
	if(pHttpConnection != NULL)
		pHttpConnection->Close();
	session.Close();
	return true;
}

3.使用tinyxml解析数据并显示

void CDemoHttpMFCDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE); // 从界面获取数据 m_url
	//OutputDebugString(m_url);
	//HttpTranslate(CHttpConnection::HTTP_VERB_GET, m_url, NULL, m_result); // 获取的数据中文乱码

	CHttpClient httpClient;
	m_result = httpClient.doGet(m_url); // 获取数据乱码

	try  
	{  
		//LPCTSTR szFileName = _T("E:\\temp\\t.html");  
		//CFile file(szFileName, CFile::modeCreate|CFile::modeWrite);  
		//file.Write((LPCTSTR)m_result, m_result.GetLength() * sizeof(TCHAR));  
		//file.Close();  
		//ShellExecute(NULL, _T("open"), szFileName, NULL, NULL, SW_SHOWNORMAL);  
	}  
	catch (CFileException* e)  
	{  
		e->ReportError();  
		e->Delete();  
	}

	wchar_t *w_result = NULL;
	w_result = toUTF8(m_result); // Unicode 转 UTF-8 解决乱码

	//char *c_result = NULL;
	//c_result = UnicodeToUtf8(m_result);

	// 解析获取到的xml数据
	TiXmlDocument *pDoc = new TiXmlDocument(); 
	CStringA szMsg;
	szMsg = w_result;
	pDoc->Parse(szMsg);
	if (pDoc->Error())
	{
		CStringA errorInfo = pDoc->ErrorDesc();
		AfxMessageBox((CString)errorInfo);
		//return NULL;
	}
	const TiXmlElement *root = pDoc->RootElement();
	for (const TiXmlNode *child = root->FirstChild(); child; child = child->NextSibling()) { // 获取节点信息
		const TiXmlElement *element = (const TiXmlElement *)child;
		CStringA value = element->Value();
		CStringA text = element->GetText();
		OutputDebugString(_T("value = ") + (CString)value + _T("\n"));
		OutputDebugString(_T("text = ") + (CString)text + _T("\n"));
		if (!strcmp(element->Value(), "userid"))
		{

		}
		if (!strcmp(element->Value(), "errorCode"))
		{

		}
		if (!strcmp(element->Value(), "errorDetail"))
		{

		}
		if (!strcmp(element->Value(), "result"))
		{

		}
		if (!strcmp(element->Value(), "name"))
		{

		}
		if (!strcmp(element->Value(), "usertype"))
		{

		}
		if (!strcmp(element->Value(), "orgcode"))
		{

		}
		// 获取元素信息
		if (!strcmp(element->Value(), "buidingList") && (child->Type() == TiXmlNode::TINYXML_ELEMENT)) 
		{
			CStringA buildingid = element->Attribute("buildingid");
			CStringA buildingname = element->Attribute("buildingname");
			CStringA floorcount = element->Attribute("floorcount");
			OutputDebugString(_T("buildingid = ") + (CString)buildingid + _T("\n"));
			OutputDebugString(_T("buildingname = ") + (CString)buildingname + _T("\n"));
			OutputDebugString(_T("floorcount = ") + (CString)floorcount + _T("\n"));
			BuildingInfo buildingInfo;
			buildingInfo.setBuildingId((CString)buildingid);
			buildingInfo.setBuildingName((CString)buildingname);
			buildingInfo.setFloorCount((CString)floorcount);
			m_buildingInfoList.push_back(buildingInfo); // 存储元素列表信息
		}
	}

	// list显示
	CRect rect;
	m_list.GetClientRect(rect);
	m_list.SetExtendedStyle(m_list.GetExtendedStyle() | LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

	m_list.InsertColumn(0, _T("Id"), LVCFMT_CENTER, rect.Width() / 3, 0);
	m_list.InsertColumn(1, _T("Name"), LVCFMT_CENTER, rect.Width() / 3, 1);
	m_list.InsertColumn(2, _T("Floor"), LVCFMT_CENTER, rect.Width() / 3, 2);

	for (int i = 0; i < m_buildingInfoList.size(); i++)
	{
		m_list.InsertItem(i, m_buildingInfoList[i].getBuildingId());
		m_list.SetItemText(i, 1, m_buildingInfoList[i].getBuildingName());
		m_list.SetItemText(i, 2, m_buildingInfoList[i].getFloorCount());
	}

	//m_result = CString(w_result);

	//UpdateData(FALSE); // 向界面传递参数
	//CDialogEx::OnOK();
}

备注:unicode 转 utf8

char* UnicodeToUtf8(CString unicode)  
{  
	int len;    
	len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)unicode, -1, NULL, 0, NULL, NULL);    
	char *szUtf8=new char[len + 1];  
	memset(szUtf8, 0, len * 2 + 2);  
	WideCharToMultiByte (CP_UTF8, 0, (LPCWSTR)unicode, -1, szUtf8, len, NULL,NULL);  
	return szUtf8;  
} 

wchar_t* toUTF8(CString& str){

	//char * pStr = (LPCSTR)(str.GetBuffer(str.GetLength()));; //取得str对象的原始字符串
	int nBufferSize = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(str.GetBuffer(str.GetLength())), -1, NULL, 0); //取得所需缓存的多少
	wchar_t *pBuffer = (wchar_t*)malloc(nBufferSize * sizeof(wchar_t));//申请缓存空间
	MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)(str.GetBuffer(str.GetLength())), -1 , pBuffer, nBufferSize*sizeof(wchar_t));//转码
	//MessageBoxW(NULL, pBuffer, L"Text", MB_OK); //显示
	//free(pBuffer); //释放缓存
	return pBuffer;
}

源码:http://download.csdn.net/detail/u012377333/9548115

你可能感兴趣的:(MFC--显示HTTP获取到XML的列表信息)