C++模拟XML解析

           在我工作碰到了打印文档,而格式和其中的固定文字经常变化。使用Xerces又过于复杂,杀鸡焉用牛刀。

简单的实现以下功能。这是一个自定义的一个解析模板,基本可以满足我要求。

$ Matthew Fan 2011-12-26 $$
<head>     公安交通管理简易处罚决定书
<\head>
<subhead>  当事人联<\subhead>

$$当事人描述信息$$
<enter>2</enter>
<text>编    号:</text><data>CurrentProtocolNum</data><enter>1</enter>
<text>当 事 人:</text><data>PersonName</data><enter>1</enter>
<text>联系方式:</text><data>PersonPhone</data><enter>1</enter>
<text>身份证号:</text><data>IDNumber</data><enter>1</enter>
<text>发证机关:</text><data>CertificationDepartment</data><enter>1</enter>
<text>准驾车型:</text><data>DriveType</data><enter>1</enter>
<text>档案编号:</text><data>FileNumber</data><enter>1</enter>
<text>号牌号码:</text><data>VehicleNum</data><enter>1</enter>
<text>号牌种类:</text><data>VehicleType</data><enter>1</enter>
<text>缴款标记:</text><data>JiaoKuanBiaoJi</data><enter>2</enter>

$$违法行为描述及处罚$$
   <space>3</space><text>当事人于</text><data>LawDate</data><text>  </text><data>LawTime</data>
<text>在</text><data>RoadNameAndKm_M</data><text>实施</text><data>IllegalActive</data>
<text>(违法代码:</text><data>LawCode</data>
<text>),法律依据:</text><data>WeiFaYiJu</data>
<text>。</text><data>FaKuanJingE</data><enter>1</enter>
<data>JingGaoBiaoJi_YiJu</data><enter>1</enter>

$$相关告知信息$$
   <space>3</space><text>当事人不服处罚决定的,可以依照《中华人民共和国行政复议法》在60日内向新疆维吾尔自治区公安厅交警总队高等级公路支队申请行政复议,或者依照《中华人民共和国行政诉讼法》在3个月内向新疆维吾尔自治区</text>
<data>SuSongJiGuan</data><text>提起行政诉讼。</text><enter>1</enter>
<data>JingGaoBiaoJi_ShuoMing</data><enter>1</enter>
<text>交通警察(签名或签章)</text><text>(</text><data>PoliceName</data><data>LawEnForceSimpleDepartID</data><text>)</text><enter>1</enter>
<text>(公安机关交通管理部门处罚盖章)</text><enter>1</enter>

$$打印印章 1:打印 0:不打印 $$
<print>1</print>

$$尾部数据$$
<enter>1</enter><text>当事人签字:</text><enter>3</enter>
<space>11</space><data>Date_China</data><enter>1</enter>
<text>备注:</text><enter>4</enter>
<text>根据《机动车驾驶证申领和使用规定》记</text><data>WeiFaKouFen</data><text>分。</text><enter>1</enter>

主要包含head:标题 subhead:副标题   enter:换行  text:固定文字  data:变量   print:打印标记 space:空格 ,以上几种关键字。


头文件:主要包含节点类DocNode主要进行,data名称和数据值的记录工作。

               AnalysisDoc主要负责解析工作。

#define NODE_NAME_SIZE 256
#define NODE_DATA_SIZE 1024

class DocNode
{
public:
	DocNode()
	{
		g_name = new char[NODE_NAME_SIZE];
		strcpy(g_name, "");
		g_data = new char[NODE_DATA_SIZE];
		strcpy(g_data, "");
	}
	DocNode(const DocNode& newDocNode)
	{
		g_name = new char[NODE_NAME_SIZE];
		strcpy(g_name, "");
		g_data = new char[NODE_DATA_SIZE];
		strcpy(g_data, "");

		strcpy(g_data, newDocNode.g_data);
		strcpy(g_name, newDocNode.g_name);
	}
	~DocNode()
	{
		delete[] g_name;
		delete[] g_data;
	}

	bool setNodeName(char* newName)
	{
		strcpy(g_name, newName);

		return true;
	}
	char* getNodeName()
	{
		return g_name;
	}

	bool setNodeData(char* newData)
	{
		strcpy(g_data, newData);

		return true;
	}
	char* getNodeData()
	{
		return g_data;
	}
private:
	char* g_name;     //关键字g
	char* g_data;     //数据内容
};

class AnalysisDoc
{
public:
	AnalysisDoc(char* fileName);					//开启文档解析器
	~AnalysisDoc();								//销毁文档解析器
	bool setNode(char* nodeName, char* nodeData);	//记录doc中的变量内容
	bool startAnalysis();							//开始解析,生成文本
	char* getContent();							//取得非打印文本,“预览文本”
	bool printDoc(/*HINSTANCE hInst, HWND hWnd, PimsPrint* printType = NULL*/); //打印文书
	void getContent(char* szContent);
	bool clearListNodeData();
private:
	bool printStamp(/*HINSTANCE hInst, HWND hWnd, PmisPrint* printType*/);      //打印程序调用
	bool analysisData(string keyName, string data);
									//取得非打印文本,“预览文本”

private:
	list<DocNode>* g_listNodes;                     //记录doc中变量内容
	char* g_content;				//记录预览内容,不含打印
	char* g_docHead;				//记录标题
	char* g_docSubhead;			        //记录副标题
	char* g_docText;				//记录正文
	char* g_docEnd;				        //记录结尾(已印章为分界线)

	char* g_docContent;			        //临时存储读取的内容,未解析内容
	int g_printFlag;				//-1 表示为赋值, 0 表示不打印, 1表示打印
};

AnalysisDoc.cpp

#include "AnalysisDoc.h"
#include <string>
#include <fstream>
using namespace std;

AnalysisDoc::AnalysisDoc(char* fileName)
{
	this->g_content = new char[NODE_DATA_SIZE*4];
	strcpy(this->g_content, "");
	this->g_docContent = new char[NODE_DATA_SIZE*4];
	strcpy(this->g_docContent, "");
	this->g_docEnd = new char[NODE_DATA_SIZE];
	strcpy(this->g_docEnd, "");
	this->g_docHead = new char[NODE_NAME_SIZE];
	strcpy(this->g_docHead, "");
	this->g_docSubhead = new char[NODE_NAME_SIZE];
	strcpy(this->g_docSubhead, "");
	this->g_docText = new char[NODE_DATA_SIZE*3];
	strcpy(this->g_docText, "");

	this->g_printFlag = -1;

	this->g_listNodes = new list<DocNode>;

	ifstream newfile_doc(fileName);
	string content = "";
	char c;
/*
	newfile_doc.open(fileName, ios::out, 0);*/
	while(newfile_doc.get(c))
	{
		content += c;
	}
	strcat(g_docContent, content.c_str());
	newfile_doc.close();

}

AnalysisDoc::~AnalysisDoc()
{
	delete[] this->g_content;
	delete[] this->g_docContent;
	delete[] this->g_docEnd;
	delete[] this->g_docHead;
	delete[] this->g_docSubhead;
	delete[] this->g_docText;

	delete g_listNodes;
}
 bool AnalysisDoc::setNode(char* nodeName, char* nodeData)
{
	DocNode newNode;
	newNode.setNodeData(nodeData);
	newNode.setNodeName(nodeName);

	g_listNodes->push_back(newNode);

	return true;
}

bool AnalysisDoc::clearListNodeData()
{
	g_listNodes->clear();

	strcpy(this->g_docEnd, "");
	strcpy(this->g_docHead, "");
	strcpy(this->g_docText, "");

	return true;
}

void AnalysisDoc::getContent(char* szContent)
{
	strcpy(szContent, this->g_content);
}

bool AnalysisDoc::startAnalysis()
{
	string* docContent = new string(g_docContent);
	string::iterator index;
	for (index = docContent->begin(); index != docContent->end(); index ++)
	{
		if ('<' == *index) //判断是否出现
		{
			index ++;
			if ('/' != *index)
			{
				string strKey = "";
				while ('>' != *index)
				{
					strKey += *index;
					index ++;
				}

				string strData = "";
				index ++;
				while ('<' != *index)
				{
					strData += *index;
					index ++;
				}

				analysisData(strKey, strData);
			}
		}
	}

	delete docContent;

	strcpy(g_content, g_docHead);
	strcat(g_content, g_docSubhead);
	strcat(g_content, g_docText);
	strcat(g_content, g_docEnd);

	return true;
}

bool AnalysisDoc::analysisData(string keyName, string data)
{
	if ("head" == keyName)
	{
		strcpy(g_docHead, data.c_str());
		strcat(g_docHead, "\r\n");
	}
	else if ("subhead" == keyName)
	{
		strcpy(g_docSubhead, data.c_str());
	}
	else if ("text" == keyName)
	{
		if (-1 == g_printFlag)
		{
			strcat(g_docText, data.c_str());
		}
		else
		{
			strcat(g_docEnd, data.c_str());
		}
	}
	else if ("data" == keyName)
	{
		char name[128] = {0};
		strcpy(name, data.c_str());
		/*if (g_listNodes->size() == 0)
			return;*/

		list<DocNode>::iterator index;
		for (index = g_listNodes->begin(); index != g_listNodes->end(); index ++)
		{
			string key = (*index).getNodeName();
			if (key == data)
			{
				if (-1 == g_printFlag)
				{
					strcat(g_docText, (*index).getNodeData());
				}
				else
				{
					strcat(g_docEnd, (*index).getNodeData());
				}
			}
		}
	}
	else if ("space" == keyName)
	{
		int num = atoi(&(*(data.begin())));
		for(int i = 0; i < num; i ++)
		{
			if (-1 == g_printFlag)
			{
				strcat(g_docText, " ");
			}
			else
			{
				strcat(g_docEnd, " ");
			}
		}
	}
	else if ("enter" == keyName)
	{
		int num = atoi(&(*(data.begin())));
		for(int i = 0; i < num; i ++)
		{
			if (-1 == g_printFlag)
			{
				strcat(g_docText, "\r\n");
			}
			else
			{
				strcat(g_docEnd, "\r\n");
			}
		}
	}
	else if ("print" == keyName)
	{
		g_printFlag = atoi(&(*(data.begin())));
	}
	else
	{
		return false;
	}
	return true;
}

char* AnalysisDoc::getContent()							//取得非打印文本,“预览文本”
{
	return this->g_content;
}

bool AnalysisDoc::printDoc(/*HINSTANCE hInst, HWND hWnd, PimsPrint* printType = NULL*/) //打印文书
{
	return true;
}

bool printStamp(/*HINSTANCE hInst, HWND hWnd, PmisPrint* printType*/)      //打印程序调用
{
	return true;
}

程序比较简单,在此就不多说了!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不会唱歌的老樊

老少爷们,来个赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值