C++解析四种不同格式的XML文件

C++解析四种不同格式的XML文件

说明

这里引用了TinyXML的开源的XML解析库,下载地址:https://sourceforge.net/projects/tinyxml/

data.h

#include "vector"


struct	PrdSNInfo 
{ 
	CString	PrdSN; 
	CString SubBoardId; 

	PrdSNInfo() 
	{ 
		PrdSN = _T(""); 
		SubBoardId = _T(""); 
	} 
};


typedef	std::vector<PrdSNInfo>	VEC_PrdSNInfo; 
typedef VEC_PrdSNInfo::iterator	VEC_PrdSNInfo_ITR;


struct	OutPrdNoInfo 
{ 
	CString	OutPrdNo; 
	CString ProductName; 

	OutPrdNoInfo() 
	{ 
		OutPrdNo = _T(""); 
		ProductName = _T(""); 
	} 
};


typedef	std::vector<OutPrdNoInfo>	VEC_OutPrdNoInfo; 
typedef VEC_OutPrdNoInfo::iterator	VEC_OutPrdNoInfo_ITR;


struct	PlanInfo 
{ 
	CString	PlanID; 
	CString PlanNo; 
	CString	OutPrdNo; 
	CString OutPrdVer; 
	CString	ProductName; 
	CString Line; 
	CString	QTY; 
	CString StartTime; 

	PlanInfo() 
	{ 
		PlanID = _T(""); 
		PlanNo = _T(""); 
		OutPrdNo = _T(""); 
		OutPrdVer = _T(""); 
		ProductName = _T("");
		Line = _T(""); 
		QTY = _T(""); 
		StartTime = _T(""); 

	} 
};


typedef	std::vector<PlanInfo>	VEC_PlanInfo; 
typedef VEC_PlanInfo::iterator	VEC_PlanInfo_ITR;
 
 

struct	ReturnParameter 
{ 
	CString Result; 
	CString ErrorCode; 
	CString ErrorMessage; 
	VEC_PrdSNInfo vec_PrdSNInfo;	
	VEC_OutPrdNoInfo vec_OutPrdNoInfo;
	VEC_PlanInfo vec_PlanInfo;

	ReturnParameter() 
	{ 
		Reset(); 
	} 
	void Reset() 
	{ 
		Result = _T(""); 
		ErrorCode = _T(""); 
		ErrorMessage = _T(""); 
		vec_PrdSNInfo.clear(); 
		vec_OutPrdNoInfo.clear();
		vec_PlanInfo.clear();
	} 
};

XMLAnalysisDlg.h

// XMLAnalysisDlg.h : 头文件
//

#pragma once
#include "tinystr.h"
#include "tinyxml.h"
#include "afx.h"
#include "data.h"
#include <string>
#include <iostream>
using namespace std;


// CXMLAnalysisDlg 对话框
class CXMLAnalysisDlg : public CDialog
{
// 构造
public:
	CXMLAnalysisDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_XMLANALYSIS_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

public:
	void XMLAnalysisFromFile(string path);
	void XMLAnalysisFromString(char* str);
	void XMLAnalysis(TiXmlDocument* myDocument);
	void ShowResult();
	char* Cstring2Char(const CString& strConvert);
public:
	PrdSNInfo m_PrdSNInfo;
	OutPrdNoInfo m_OutPrdNoInfo;
	PlanInfo m_PlanInfo;
	ReturnParameter m_ReturnParameter;
public:
	afx_msg void OnBnClickedOk();
public:
	CString m_strXML;
public:
	CString m_strResult;
public:
	afx_msg void OnBnClickedOk2();
public:
	CString m_Result;
public:
	CString m_ErrorCode;
public:
	CString m_ErrorMessage;
};

XMLAnalysisDlg.cpp

// XMLAnalysisDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "XMLAnalysis.h"
#include "XMLAnalysisDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// 对话框数据
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// CXMLAnalysisDlg 对话框




CXMLAnalysisDlg::CXMLAnalysisDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CXMLAnalysisDlg::IDD, pParent)
	, m_strXML(_T(""))
	, m_strResult(_T(""))
	, m_Result(_T(""))
	, m_ErrorCode(_T(""))
	, m_ErrorMessage(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CXMLAnalysisDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, m_strXML);
	DDX_Text(pDX, IDC_EDIT15, m_Result);
	DDX_Text(pDX, IDC_EDIT3, m_ErrorCode);
	DDX_Text(pDX, IDC_EDIT4, m_ErrorMessage);
}

BEGIN_MESSAGE_MAP(CXMLAnalysisDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDOK, &CXMLAnalysisDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDOK2, &CXMLAnalysisDlg::OnBnClickedOk2)
END_MESSAGE_MAP()


// CXMLAnalysisDlg 消息处理程序

BOOL CXMLAnalysisDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	CEdit *p_Edit;
	p_Edit = (CEdit*)GetDlgItem(IDC_EDIT_STRING);
	p_Edit->SetLimitText(UINT_MAX);		//设置Edit Control容纳最大字符数
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CXMLAnalysisDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CXMLAnalysisDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标显示。
//
HCURSOR CXMLAnalysisDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void CXMLAnalysisDlg::XMLAnalysisFromFile(string path)
{
	//创建文件对象  
	TiXmlDocument * myDocument = new TiXmlDocument();  
	//加载文件数据  
	myDocument->LoadFile(path.c_str());  
	XMLAnalysis(myDocument);
}


void CXMLAnalysisDlg::XMLAnalysisFromString(char* str)
{
	TiXmlDocument* myDocument = new TiXmlDocument();
	myDocument->Parse(str);
	XMLAnalysis(myDocument);
}


void CXMLAnalysisDlg::XMLAnalysis(TiXmlDocument* myDocument)
{
	//获取根节点数据  
	TiXmlElement *root = myDocument->RootElement();

	m_ReturnParameter.Reset();

	TiXmlElement* elemResult = root->FirstChildElement("Result");
	if (elemResult!=NULL)
	{
		m_ReturnParameter.Result = elemResult->GetText();
	}
	TiXmlElement* elemErrorCode = root->FirstChildElement("ErrorCode");
	if (elemErrorCode!=NULL)
	{
		m_ReturnParameter.ErrorCode = elemErrorCode->GetText();
	}
	TiXmlElement* elemErrorMessage = root->FirstChildElement("ErrorMessage");
	if (elemErrorMessage!=NULL)
	{
		m_ReturnParameter.ErrorMessage = elemErrorMessage->GetText();
	}
	
	/*<?xml version="1.0" encoding="UTF-8"?>
		<ReturnParameter>
		<Result>PASS</Result>
		<ErrorCode></ErrorCode>
		<ErrorMessage></ErrorMessage>
		<PrdSNInfo>
		<PrdSNs>
		<PrdSN>SN0000000001</PrdSN>
		<SubBoardId>1</SubBoardId>
		</PrdSNs>
		<PrdSNs>
		<PrdSN>SN0000000002</PrdSN>
		<SubBoardId>2</SubBoardId>
		</PrdSNs>
		<PrdSNs>
		<PrdSN>SN0000000003</PrdSN>
		<SubBoardId>3</SubBoardId>
		</PrdSNs>
		<PrdSNs>
		<PrdSN>SN0000000004</PrdSN>
		<SubBoardId>4</SubBoardId>
		</PrdSNs>
		</PrdSNInfo>
		</ReturnParameter>*/
	TiXmlElement* elemPrdSN = root->FirstChildElement("PrdSNInfo");
	if (elemPrdSN!=NULL)
	{
		for(TiXmlElement* elem = elemPrdSN->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement())
		{
			const char* strPrdSN = elem->FirstChildElement("PrdSN")->GetText();
			m_PrdSNInfo.PrdSN = strPrdSN;
			const char* strSubBoardId = elem->FirstChildElement("SubBoardId")->GetText();
			m_PrdSNInfo.SubBoardId = strSubBoardId;
			m_ReturnParameter.vec_PrdSNInfo.push_back(m_PrdSNInfo);
		}
	}

	/*<?xml version="1.0" encoding="UTF-8"?>
		<ReturnParameter>
		<Result>PASS</Result>
		<ErrorCode />
		<ErrorMessage />
		<OutPrdNoList>
		<OutPrdNoInfo>
		<OutPrdNo>PN00001</OutPrdNo>
		<ProductName>X1 Borad</ProductName>
		</OutPrdNoInfo>
		<OutPrdNoInfo>
		<OutPrdNo>PN00002</OutPrdNo>
		<ProductName>X2 Borad</ProductName>
		</OutPrdNoInfo>
		</OutPrdNoList>
		</ReturnParameter>*/
	TiXmlElement* elemOutPrdNo = root->FirstChildElement("OutPrdNoList");
	if (elemOutPrdNo!=NULL)
	{
		for(TiXmlElement* em = elemOutPrdNo->FirstChildElement(); em != NULL; em = em->NextSiblingElement())
		{
			const char* strOutPrdNo = em->FirstChildElement("OutPrdNo")->GetText();
			m_OutPrdNoInfo.OutPrdNo = strOutPrdNo;
			const char* strProductName = em->FirstChildElement("ProductName")->GetText();
			m_OutPrdNoInfo.ProductName = strProductName;
			m_ReturnParameter.vec_OutPrdNoInfo.push_back(m_OutPrdNoInfo);
		}
	}
	
	/*<?xml version="1.0" encoding="UTF-8"?>
		<ReturnParameter>
		<Result>PASS</Result>
		<ErrorCode />
		<ErrorMessage />
		<PlanNoList>
		<PlanInfo>
		<PlanID>190410023132-ff07df12-3b63-44e4-aede</PlanID>
		<PlanNo>WO000001</PlanNo>
		<OutPrdNo>PN00001</OutPrdNo>
		<OutPrdVer>01</OutPrdVer>
		<ProductName>X1</ProductName>
		<Line>SMT-01</Line>
		<QTY>10000</QTY>
		<StartTime>2019-04-10 10:10:10</StartTime>
		</PlanInfo>
		<PlanInfo>
		<PlanID>190412002313-ff07df12-3b63-44e4-aedf</PlanID>
		<PlanNo>WO000002</PlanNo>
		<OutPrdNo>PN00001</OutPrdNo>
		<OutPrdVer>01</OutPrdVer>
		<ProductName>X1</ProductName>
		<Line>SMT-01</Line>
		<QTY>5000</QTY>
		<StartTime>2019-04-12 08:10:10</StartTime>
		</PlanInfo>
		</PlanNoList>
		</ReturnParameter>*/
	TiXmlElement* elemPlan = root->FirstChildElement("PlanNoList");
	if (elemPlan!=NULL)
	{
		for(TiXmlElement* em = elemPlan->FirstChildElement(); em != NULL; em = em->NextSiblingElement())
		{
			const char* strPlanID = em->FirstChildElement("PlanID")->GetText();
			m_PlanInfo.PlanID = strPlanID;
			const char* strPlanNo = em->FirstChildElement("PlanNo")->GetText();
			m_PlanInfo.PlanNo = strPlanNo;
			const char* strOutPrdNo = em->FirstChildElement("OutPrdNo")->GetText();
			m_PlanInfo.OutPrdNo = strOutPrdNo;
			const char* strOutPrdVer = em->FirstChildElement("OutPrdVer")->GetText();
			m_PlanInfo.OutPrdVer = strOutPrdVer;
			const char* strProductName = em->FirstChildElement("ProductName")->GetText();
			m_PlanInfo.ProductName = strProductName;
			const char* strLine = em->FirstChildElement("Line")->GetText();
			m_PlanInfo.Line = strLine;
			const char* strQTY = em->FirstChildElement("QTY")->GetText();
			m_PlanInfo.QTY = strQTY;
			const char* strStartTime = em->FirstChildElement("StartTime")->GetText();
			m_PlanInfo.StartTime = strStartTime;
			m_ReturnParameter.vec_PlanInfo.push_back(m_PlanInfo);
		}
	}

	/*<?xml version="1.0" encoding="UTF-8"?>
		<ReturnParameter>
		<Result>PASS</Result>
		<ErrorCode />
		<ErrorMessage />
		<PrdSNs>
		<PrdSN>SN0000000001</PrdSN>
		<PrdSN>SN0000000002</PrdSN>
		<PrdSN>SN0000000003</PrdSN>
		<PrdSN>SN0000000004</PrdSN>
		</PrdSNs>
		</ReturnParameter>*/
	TiXmlElement* elemPrdSNs = root->FirstChildElement("PrdSNs");
	if (elemPrdSNs!=NULL)
	{
		for(TiXmlElement* elem = elemPrdSNs->FirstChildElement(); elem != NULL; elem = elem->NextSiblingElement())
		{
			const char* strPrdSN = elem->GetText();
			m_PrdSNInfo.PrdSN = strPrdSN;
			m_ReturnParameter.vec_PrdSNInfo.push_back(m_PrdSNInfo);
		}
	}

	delete myDocument;
}


void CXMLAnalysisDlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strFilePath;
	string path;
	CString strFilter = _T("(*.xml)|*.xml||"); 
	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, strFilter); 
	dlg.m_ofn.lpstrTitle = _T("请选择一个XML文件"); 
	if(dlg.DoModal() == IDOK) 
	{ 
		strFilePath = dlg.GetPathName();
		path=CW2A(strFilePath.GetString());
		XMLAnalysisFromFile(path);
		ShowResult();
	}
	else
		return ;
}



void CXMLAnalysisDlg::ShowResult()
{
	m_Result = _T("");
	m_ErrorCode = _T("");
	m_ErrorMessage = _T("");
	m_Result.Format(_T("Result=%s"),m_ReturnParameter.Result); 
	m_ErrorCode.Format(_T("ErrorCode=%s"),m_ReturnParameter.ErrorCode); 
	m_ErrorMessage.Format(_T("ErrorMessage=%s"),m_ReturnParameter.ErrorMessage); 
	UpdateData(FALSE);							  
}	


void CXMLAnalysisDlg::OnBnClickedOk2()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	char* str=Cstring2Char(m_strXML);
	XMLAnalysisFromString(str);
	ShowResult();
	delete []str;
	str=NULL;
}


char* CXMLAnalysisDlg::Cstring2Char(const CString& strConvert)
{
	long nAnsiCount = 0;
	//先计算该宽字符串所对应ANSI字符串的长度,包括字符串结束符
	nAnsiCount = WideCharToMultiByte(CP_ACP,0,strConvert,-1,NULL,0,NULL,NULL);
	if (nAnsiCount<1) return NULL;
	char* pChar = new char[nAnsiCount];  //申请空间
	memset(pChar,0,nAnsiCount);
	WideCharToMultiByte(CP_ACP,0,strConvert,-1,pChar,nAnsiCount,NULL,NULL);//转换字符
	return pChar;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值