声明:本文是我项目过程中的一个小小的Demo,里面涉及到的知识是使用HTTP获取XML数据,然后使用tinyxml库解析获取到的XML数据。使用STL的Vector保存列表信息。最后使用List Control显示列表信息。
效果图:
#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) { }
#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; }
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(); }
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; }