C语言实现XML生成解析库(XML扩展)

449 阅读23分钟

  放假期间在家有点无聊,前一段时间对XML的生成、解析比较感兴趣,便根据自己对XML的理解结合链表实现一个XML的制作与解析的结构。

设计采用了固定格式头信息加自定义头信息:

  《?xml version="xml" encoding="Utf-8"? 》这段数据属于固定格式头信息,里面的"xml"和"Utf-8"可以通过库函数进行修改; 《?567?》这段数据属于自定义头信息,可以自由增加;

节点、元素以及元素数据采用名称+标签类型+标签名称+标签数据组成,其中名称不能省略,类型、数据名称以及数据可以任意增加:

  《test3 table1 tablename1="tabledata1"》这段数据中 test3是节点名称,table1是节点标签类型,tablename1是标签名称,tabledata1是标签数据; 下面说下库的结构:

首先看下效果图: 这里写图片描述

大量数据下的效果图: 这里写图片描述

设计采用了头信息数据一个部分,节点一个部分(节点结构内包含元素结构、标签结构、数据等结构信息),设计采用了链表做遍历方式,并且用虚析构函数做退出前的内存释放,保证了内存不会泄露;

下面贴上调用函数头文件:

#pragma once
#include "TestXML.h"
struct LkyXML : public TestXML,public TestAnalyXML
{
	LkyXML();
	virtual ~LkyXML();
	bool		LCreateHeadInfo(char *vesion,char *encoding);//如果不调用这个函数将会使用一个默认值
	bool		LAddHeadInfo(char *HeadData,int HeadDataLen);
	PHeadInfo	LCheckHeadInfo();//查看增加的头信息结构
	bool		LCreateNode(char *Nodename,int NodenameLen);//清除之前所有的节点 重新开始创建节点
	bool		LAddNode(char *Nodename,int NodenameLen);//在当前的节点后面开始顺序增加
	bool		LAddNodeTable(char *Tabletype,int TabletypeLen,char *Tablename,int TableLen,char *TableData,int TableDataLen);//在当前节点下增加标签
	
	bool		LCreateElement(char *Elename,int ElenameLen);//清除当前节点所有的元素 重新开始创建元素
	bool		LAddElement(char *Elename,int ElenameLen);
	bool		LAddElementTable(char *EleTabletype,int EleTabletypeLen,char *EleTablename,int EleTableLen,char *EleTableData,int EleTableDataLen);
	bool		LAddElementData(char *ElaDataname,int ElaDatanameLen,char *EleData,int EleDataLen);
	bool		LAddElementDataTable(char *DataTabletype,int DataTabletypeLen,char *DataTablename,int DataTableLen,char *DataTableData,int DataTableDataLen);

	bool		LCreateXML();//在有节点的情况下才能生成XML数据
	bool		LCreateXMLFile(char *Filename);
	char *      LGetXMLData();
	bool		LFreeAllNode();
	PNode		LFreeNode(PNode freenode);//返回下一个节点 如果没有返回空节点
	PElement	LFreeElement(PElement freeEle);//返回下一个元素 如果没有返回空的元素

	PNode		LAnalyXML(char *XmlData,bool nfile);//解析XML并且返回节点头
	PHeadInfo	LGetHeadInfo();//获取解析到的信息头,如果没有返回空
	PNode       LGetAnalyNode();
	bool        LAnalyToHeadInfo(PHeadInfo _node);//解析到的头信息保存到XML生成类,并且原来的生成类信息删除
	bool        LAnalyAddHeadInfo(PHeadInfo _node);//解析到的头信息保存到XML生成类,原来的生成类信息不删除
	bool		LAnalyToNode(PNode _node);//解析到的节点保存到XML生成类节点,并且原来的生成类节点删除
	bool		LAnalyAddNode(PNode _node);//解析到的节点保存到XML生成类节点, 原来的生成类节点不删除
private:
	char		*LdynamicMem(void *buffer);
	PNode       LGetCurrentNode();
};

调用函数源文件:

#include "stdafx.h"
#include "LkyXML.h"

LkyXML::LkyXML()
{

}
LkyXML::~LkyXML()
{

}
char* LkyXML::LdynamicMem(void *buffer)
{
	if (0 == buffer)
		return 0;
	int nlen = strlen((char*)buffer);
	if (0 == nlen)
		return 0;
	char *buff = (char*)malloc(nlen + 1);
	memset(buff,0,nlen + 1);
	memcpy(buff,(char*)buffer,nlen);
	return buff;
}

bool LkyXML::LCreateHeadInfo(char *vesion,char *encoding)
{
	if (CreateHeadInfo(vesion,encoding))
		return true;
	return false;;
}
bool LkyXML::LAddHeadInfo(char *HeadData,int HeadDataLen)
{
	if (AddHeadInfo(HeadData,HeadDataLen))
		return true;
	return false;
}
PHeadInfo LkyXML::LCheckHeadInfo()
{
	return CheckHeadInfo();
}
bool LkyXML::LCreateNode(char *Nodename,int NodenameLen)
{
	if (!FreeAllNode())
		return false;
	if (!AddNode(Nodename,NodenameLen))
		return false;
	return true;
}
bool LkyXML::LAddNode(char *Nodename,int NodenameLen)
{
	if (!AddNode(Nodename,NodenameLen))
		return false;
	return true;
}
bool LkyXML::LAddNodeTable(char *Tabletype,int TabletypeLen,char *Tablename,int TableLen,char *TableData,int TableDataLen)
{
	if (!AddNodeTable(LdynamicMem(Tabletype),TableDataLen,LdynamicMem(Tablename),TableLen,LdynamicMem(TableData),TableDataLen));
	return false;
	return true;
}
bool LkyXML::LCreateElement(char *Elename,int ElenameLen)
{
	PNode _node = LGetCurrentNode();
	while (_node->ElementHead)
		_node->ElementHead = FreeElement(_node->ElementHead);
	_node->Element = _node->ElementHead;
	if (!AddElement(Elename,ElenameLen))
		return false;
	return true;
}
bool LkyXML::LAddElement(char *Elename,int ElenameLen)
{
	if (!AddElement(Elename,ElenameLen))
		return false;
	return true;
}
bool LkyXML::LAddElementTable(char *EleTabletype,int EleTabletypeLen,char *EleTablename,int EleTableLen,char *EleTableData,int EleTableDataLen)
{
	if (!AddElementTable(LdynamicMem(EleTabletype),EleTabletypeLen,LdynamicMem(EleTablename),EleTableLen,LdynamicMem(EleTableData),EleTableDataLen))
		return false;
	return true;
}
bool LkyXML::LAddElementData(char *ElaDataname,int ElaDatanameLen,char *EleData,int EleDataLen)
{
	if (!AddElementData(LdynamicMem(ElaDataname),ElaDatanameLen,LdynamicMem(EleData),EleDataLen))
		return false;
	return true;
}
bool LkyXML::LAddElementDataTable(char *DataTabletype,int DataTabletypeLen,char *DataTablename,int DataTableLen,char *DataTableData,int DataTableDataLen)
{
	if (!AddElementDataTable(LdynamicMem(DataTabletype),DataTabletypeLen,LdynamicMem(DataTablename),DataTableLen,LdynamicMem(DataTableData),DataTableDataLen))
		return false;
	return true;
}
bool LkyXML::LCreateXML()
{
	if (!CreateXML())
		return false;
	return true;
}
bool LkyXML::LCreateXMLFile(char *Filename)
{
	if (!CreateXMLFile(Filename))
		return false;
	return true;
}
bool LkyXML::LFreeAllNode()
{
	if (!FreeAllNode())
		return false;
	return true;
}
PNode LkyXML::LFreeNode(PNode freenode)
{
	return FreeNode(freenode);
}
PElement LkyXML::LFreeElement(PElement freeEle)
{
	return FreeElement(freeEle);
}
PNode LkyXML::LAnalyXML(char *XmlData,bool nfile)
{
	return AnalyXML(XmlData,nfile);
}
PHeadInfo LkyXML::LGetHeadInfo()
{
	return GetHeadInfo();
}
PNode LkyXML::LGetCurrentNode()
{
	return GetGetCurrentNode();
}
bool LkyXML::LAnalyToNode(PNode _node)
{
	if (!FreeAllNode())
		return false;
	if (!AddValidNode(_node))
		return false;
	return true;
}
bool LkyXML::LAnalyAddNode(PNode _node)
{
	if (!AddValidNode(_node))
		return false;
	return true;
}
PNode LkyXML::LGetAnalyNode()
{
	return GetAnalyNode();
}
bool LkyXML::LAnalyToHeadInfo(PHeadInfo _node)
{
	FreeHeadInfo();
	while (_node)
	{

		AddHeadInfo(_node->HeadData,_node->HeadDataLen);
		_node = _node->Next;
	}
	return true;
}
bool LkyXML::LAnalyAddHeadInfo(PHeadInfo _node)
{
	if (0 == _node)
		return false;
	while (_node)
	{

		AddHeadInfo(_node->HeadData,_node->HeadDataLen);
		_node = _node->Next;
	}
	return true;
}
char *LkyXML::LGetXMLData()
{
	int nLen = GetXMLDataLen();
	char *xmldata = (char*)malloc(nLen + 1);
	memset(xmldata,0,nLen + 1);
	memcpy(xmldata,GetXMLData(),nLen);
	return xmldata;
}

XML核心头文件:

/*
*************************************************************
*李坤昱
*QQ:326087275@qq.com
CSDN:http://blog.csdn.net/a29562268
**************************************************************
*/
#pragma once

#define		XMLBUFFER 1024 * 1024 * 100//xml最大不超过100M,首先分配100M生成XML后释放掉多余的内存
typedef struct Table
{
	char	*Tabletype;//<node type xml="123"> Tabletype表示type TabletypeLen为0是表示不指定
	int		TabletypeLen;
	char	*Tablename;//<node type xml="123"> Tablename表示xml Tablelen为0表示不指定
	int		Tablelen;
	char	*TableData;//<node type xml="123"> TableData表示123 TableDataLen为0表示无数据
	int		TableDataLen;
	Table	*Next;//一般情况下标签只有一份 目前使用第一层
}*PTable;
typedef struct NodeDataInfo
{
	char			Dataname[256];//数据名称
	unsigned char	DatanameLen;//数据名称长度
	char			*Data;//数据信息
	int				DataLen;//数据信息长度
	PTable			DataTable;
	NodeDataInfo	*Next;
}*PNodeDataInfo;

typedef struct Element
{
	char			name[256];//字符串长度最多0-254,255为0
	unsigned char	nameLen;
	PNodeDataInfo	NodeDataHead,NodeData;
	PTable			TableHead,table;//标签信息头
	Element			*Prev,*Next;
}*PElement;
typedef struct Node
{
	char			name[256];//字符串长度最多0-254,255为0
	unsigned char	nameLen;
	//PNodeDataInfo NodeData;
	PTable			TableHead;//标签信息头
	Node			*Prev,*Next;
	PElement		ElementHead,Element;//元素信息
}*PNode;

typedef struct HeadInfo
{
	char		*HeadData;
	int			HeadDataLen;
	HeadInfo	*Next;
}*PHeadInfo;
struct TestXML
{
	TestXML();
	virtual ~TestXML();
	bool				CreateHeadInfo(char *vesion,char *encoding);//如果不调用这个函数将会使用一个默认值
	bool				AddHeadInfo(char *HeadData,int HeadDataLen);
	bool                FreeHeadInfo();
	PHeadInfo			CheckHeadInfo();
	bool				AddNode(char *Nodename,int NodenameLen);
	bool				AddNodeTable(char *Tabletype,int TabletypeLen,char *Tablename,int TableLen,char *TableData,int TableDataLen);
	bool                AddValidNode(PNode _node);//增加节点到链表尾部
	PNode				GetGetCurrentNode();
	//bool AddNodeData(char *NodeData,int NodeDataLen);//节点下没有数据 这个函数不使用
	bool				AddElement(char *Elename,int ElenameLen);
	bool				AddElementTable(char *EleTabletype,int EleTabletypeLen,char *EleTablename,int EleTableLen,char *EleTableData,int EleTableDataLen);
	bool                AddValidElement(PElement _element);//增加元素到链表尾部                
	bool				AddElementData(char *ElaDataname,int ElaDatanameLen,char *EleData,int EleDataLen);
	bool				AddElementDataTable(char *DataTabletype,int DataTabletypeLen,char *DataTablename,int DataTableLen,char *DataTableData,int DataTableDataLen);
	bool				CreateXML();
	bool				CreateXMLFile(char *Filename);
	char *              GetXMLData();
	int                 GetXMLDataLen();
	bool				FreeAllNode();
	PNode				FreeNode(PNode freenode);//返回下一个节点 如果没有返回空节点
	PElement			FreeElement(PElement freeEle);

private:
	bool				FindNote(char *Nodename);
	bool				FindElement(char *Nodename);
	int					FindData(const char *srcdata,const char *seekdata,int srclen);//如果有返回实际位置 ,没有返回-1
	bool				FindHeadInfo(char* HeadData,int HeadDataLen);
	void				InitHeadInfo();
	int					GenerateNode(PNode nodeInfo,char* OutInfo);
	int					GenerateElement(PElement Element,char* OutInfo);
	bool				FreeTable(PTable freeTable);
	char				*dynamicMem(void *buffer);
	bool				ValidNode(PNode _node);//经过查找不重复调用这个函数添加节点
private:
	PHeadInfo			headInfo;
	PNode				nodeHead,node;
	char				*XMLData;
	int					XMLDataLen;
	FILE				*Generatefile; 
};

struct TestAnalyXML
{
	TestAnalyXML();
	virtual ~TestAnalyXML();
	PHeadInfo			GetHeadInfo();
	bool                AnalyFreeHeadInfo();
	PNode				GetAnalyNode();
	PNode				AnalyXML(char *XmlData,bool nfile);//解析XML返回节点 信息头数据自从放置进入信息头结构 如果nfile为1属于文件
	bool				AnalyFreeAllNode();
	PNode				AnalyFreeNode(PNode freenode);//返回下一个节点 如果没有返回空节点
	PElement			AnalyFreeElement(PElement freeEle);
	bool				AnalyFreeTable(PTable freeTable);
private:
	PNode				AnalyFile(char *XmlData,bool nfile);
	PNode				AnalyData(const char *XmlData);
	PNode				AnalyNodeName(const char *XmlData);
	int					AnalyHeadInfo(const char *XmlData);
	PTable				AnalyTable(const char *XmlData);
	PElement			AnalyElement(const char*data,int nlen);
	PNodeDataInfo		AnalyEleDataInfo(const char*data,int nlen);
	int					Findnumber(const char *srcdata,const char *seekdata,int srclen);//查找有多少个这样的数据 没有返回0
	int					FindData(const char *srcdata,const char *seekdata,int srclen);//如果有返回实际位置 ,没有返回-1
	bool				FindHeadInfo(char* HeadData,int HeadDataLen);
private:
	PHeadInfo			headInfo;
	PNode				nodeHead,node;
	char				*XMLData;
	int					XMLDataLen; 
	FILE				*Generatefile; 
};

XML核心源文件:

/*
*************************************************************
*李坤昱
*QQ:326087275@qq.com
CSDN:http://blog.csdn.net/a29562268
**************************************************************
*/
#include "stdafx.h"
#include "TestXML.h"

TestXML::TestXML():nodeHead(0),node(0),XMLData(0),XMLDataLen(0)
{
	InitHeadInfo();
}
TestXML::~TestXML()
{
	FreeHeadInfo();
	FreeAllNode();
}
bool TestXML::FreeHeadInfo()
{
	if (0 == headInfo)
		return false;
	PHeadInfo head = headInfo;
	while (head)
	{
		headInfo = headInfo->Next;
		free(head->HeadData);
		free(head);
		head = 0;
		head = headInfo;
	}
	return true;
}
bool TestXML::FreeAllNode()
{
	if (!nodeHead)
		return false;
	PNode freeNode = nodeHead;
	while (freeNode)
	{
		freeNode = FreeNode(freeNode);
	}
	nodeHead = node = 0;
	return true;
}
PNode TestXML::FreeNode(PNode freenode)
{
	if (!freenode)
		return freenode;
	PNode Node = freenode->Next;
	if (Node && freenode->ElementHead)
	{
		//首先释放元素
		PElement element = freenode->ElementHead;
		while (element)
		{
			element = FreeElement(element);
		}
	}
	if (freenode->TableHead)
	{
		FreeTable(freenode->TableHead);
	}
	free(freenode);
	freenode = 0;
	return Node;
}
PElement TestXML::FreeElement(PElement freeEle)
{
	if (!freeEle)
		return freeEle;
		
	//保存下一个元素
	PElement next = freeEle->Next;
	//释放数据头
	PNodeDataInfo dataHead = freeEle->NodeDataHead;
	while (dataHead)
	{
		PNodeDataInfo next = dataHead->Next;
		if (dataHead->DataTable)
			FreeTable(dataHead->DataTable);
		free(dataHead->Data);
		free(dataHead);
		dataHead = next;
		
	}
	//释放元素标签
	if (freeEle->TableHead)
		FreeTable(freeEle->TableHead);
	free(freeEle);
	freeEle = 0;
	return next;
}
bool TestXML::FreeTable(PTable freeTable)
{
	if (!freeTable)
		return false;
	PTable tab = freeTable;
	while (tab)
	{
		PTable next = tab->Next;
		free(tab->TableData);
		free(tab->Tablename);
		free(tab->Tabletype);
		free(tab);
		tab = next;
	}
	return true;
}
bool TestXML::FindNote(char *Nodename)
{
	PNode _node = nodeHead;
	int nnameLen = strlen(Nodename);
	while (_node)
	{
		bool bequal = true;
		if (_node->nameLen != nnameLen)
			bequal = false;
		for (int i = 0;bequal && i < nnameLen;i++)
		{
			if (*(_node->name + i) == *(Nodename + i))
				bequal = true;
			else
				bequal = false;
		}
		if (bequal)
			return true;
		_node = _node->Next;
	}
	return false;
}
bool TestXML::FindElement(char *Nodename)
{
	PElement _node = node->Element;
	int nnameLen = strlen(Nodename);
	while (_node)
	{
		bool bequal = true;
		if (_node->nameLen != nnameLen)
			bequal = false;
		for (int i = 0;bequal && i < nnameLen;i++)
		{
			if (*(_node->name + i) == *(Nodename + i))
				bequal = true;
			else
				bequal = false;
		}
		if (bequal)
			return true;
		_node = _node->Next;
	}
	return false;
}
int TestXML::FindData(const char *srcdata,const char *seekdata,int srclen)
{
	const char* psrc = srcdata;
	const char* pseek = seekdata;
	int nLen = strlen(pseek);
	int FindLen = 0;
	
	for (;FindLen < srclen;)
	{	
		bool bequal = true;
		for (int it = 0;bequal && it < nLen;it++)
		{
			if (*(psrc + FindLen) == *(pseek + it))
				bequal = true;
			else
				bequal = false;
			++FindLen;
		}
		if (bequal)
		{	
			FindLen -= nLen;
			return FindLen;
		}
			
	}
	return -1;
}
bool TestXML::FindHeadInfo(char* HeadData,int HeadDataLen)
{
	if (0 == HeadData || 0 >= HeadDataLen)
		return true;
	PHeadInfo headinfo = headInfo;
	while (headinfo)
	{
		bool bequal = true;
		if (headinfo->HeadDataLen != HeadDataLen)
			bequal = false;
		for (int i = 0;bequal && i < HeadDataLen;i++)
		{
			if (*(headinfo->HeadData + i) == *(HeadData + i))
				bequal = true;
			else
				bequal = false;
		}
		if (bequal)
			return true;
		headinfo = headinfo->Next;
	}
	return false;
}
void TestXML::InitHeadInfo()
{
	headInfo = (PHeadInfo)malloc(sizeof(HeadInfo));
	int nLen = strlen("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
	headInfo->HeadData = (char*)malloc(nLen + 1);
	memset(headInfo->HeadData,0,(nLen + 1));
	memcpy(headInfo->HeadData,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",nLen);
	headInfo->HeadDataLen = nLen;
	headInfo->Next = 0;
}
bool TestXML::CreateHeadInfo(char* vesion,char* encoding)
{
	if (0 == vesion || 0 == encoding)
	 return false;
	if (headInfo->HeadData)
		free(headInfo->HeadData);
	int nLen = (strlen("<?xml version=\"") + strlen("\" encoding=\"") + strlen(vesion) + strlen(encoding) + strlen("\"?>"));
	char *headData = (char*)malloc(sizeof(char) * nLen + 1);
	memset(headInfo->HeadData,0,sizeof(char) * nLen + 1);
	sprintf(headData,"<?xml version=\"%s\" encoding=\"%s\"?>",vesion,encoding);
	headInfo->HeadData = headData;
	headInfo->HeadDataLen = strlen(headData);
	return true;
}

bool TestXML::AddHeadInfo(char* HeadData,int HeadDataLen)
{
	if (0 == HeadData || 0 >= HeadDataLen)
		return false;
	if (FindHeadInfo(HeadData,HeadDataLen))
		return false;
	char *headData = (char*)malloc(HeadDataLen + 1);
	memset(headData,0,(HeadDataLen + 1));
	memcpy(headData,HeadData,HeadDataLen);
	
	if (0 == headInfo)
	{
		headInfo = (PHeadInfo)malloc(sizeof(HeadInfo));
		headInfo->HeadData = headData;
		headInfo->HeadDataLen = HeadDataLen;
		headInfo->Next = 0;
	}
	else
	{
		PHeadInfo Info = headInfo;
		while (0 != Info->Next)
			Info = Info->Next;
		Info->Next = (PHeadInfo)malloc(sizeof(HeadInfo));
		Info->Next->HeadData = headData;
		Info->Next->HeadDataLen = HeadDataLen;
		Info->Next->Next = 0;
	}
	return true;
}
bool TestXML::AddNode(char *Nodename,int NodenameLen)
{
	if (0 == Nodename || 0 >= NodenameLen)
		return false;
	//如果增加的节点已经储存了那么返回失败
	if (FindNote(Nodename))
		return false;
	if (0 == nodeHead)
	{
		nodeHead = (PNode)malloc(sizeof(Node));
		memset(nodeHead,0,sizeof(Node));
		memcpy(nodeHead->name,Nodename,NodenameLen);
		nodeHead->nameLen = NodenameLen;
		node = nodeHead;
		return true;
	}
	while (0 != node->Next)
		node = node->Next;
	node->Next = (PNode)malloc(sizeof(Node));
	memset(node->Next,0,sizeof(Node));
	node->Next->Prev = node;
	node = node->Next;
	node->nameLen = NodenameLen;
	memcpy(node->name,Nodename,NodenameLen);
	return true;
}
bool TestXML::AddNodeTable(char *Tabletype,int TabletypeLen,char *Tablename,int TableLen,char *TableData,int TableDataLen)
{
	if (0 == node)
		return false;
	if ((0 == Tabletype && 0 == Tablename && 0 == TableData) || (0 >= TabletypeLen && 0 >= TableLen && 0 >= TableDataLen))
		return false;
	if (0 == node->TableHead)
	{
		node->TableHead = (PTable)malloc(sizeof(Table));
		node->TableHead->Tabletype = Tabletype;
		node->TableHead->TabletypeLen = TabletypeLen;
		node->TableHead->Tablename = Tablename;
		node->TableHead->Tablelen = TableLen;
		node->TableHead->TableData = TableData;
		node->TableHead->TableDataLen = TableDataLen;
		node->TableHead->Next = 0;
		return true;
	}
	PTable table = node->TableHead;
	while (0 != table->Next)
		table = table->Next;
	table->Next = (PTable)malloc(sizeof(Table));
	table = table->Next;
	table->Tabletype = Tabletype;
	table->TabletypeLen = TabletypeLen;
	table->Tablename = Tablename;
	table->Tablelen = TableLen;
	table->TableData = TableData;
	table->TableDataLen = TableDataLen;
	table->Next = 0;
	return true;
}
PNode TestXML::GetGetCurrentNode()
{
	return node;
}
bool TestXML::ValidNode(PNode _node)
{
	if (0 == _node)
		return false;
	
		if (0 == node)
		{
			node = (PNode)malloc(sizeof(Node));
			nodeHead = node;
			memset(node,0,sizeof(Node));
			memcpy(node->name,_node->name,_node->nameLen);
			node->nameLen = _node->nameLen;
			while (_node->TableHead)
			{
				AddNodeTable(dynamicMem(_node->TableHead->Tabletype),_node->TableHead->TabletypeLen,dynamicMem(_node->TableHead->Tablename)\
					,_node->TableHead->Tablelen,dynamicMem(_node->TableHead->TableData),_node->TableHead->TableDataLen);
				_node->TableHead = _node->TableHead->Next;
			}
			AddValidElement(_node->ElementHead);
		}
		else
		{
			while (node && 0 != node->Next)
				node = node->Next;
			node->Next = (PNode)malloc(sizeof(Node));
			memset(node->Next,0,sizeof(Node));
			node->Next->Prev = node;
			node = node->Next;
			memcpy(node->name,_node->name,_node->nameLen);
			node->nameLen = _node->nameLen;
			while (_node->TableHead)
			{
				AddNodeTable(dynamicMem(_node->TableHead->Tabletype),_node->TableHead->TabletypeLen,dynamicMem(_node->TableHead->Tablename)\
					,_node->TableHead->Tablelen,dynamicMem(_node->TableHead->TableData),_node->TableHead->TableDataLen);
				_node->TableHead = _node->TableHead->Next;
			}
			AddValidElement(_node->ElementHead);
		}
		//_node = _node->Next;
	
	return true;
}
bool TestXML::AddValidNode(PNode _node)
{
	if (0 == _node)
		return false;
	//判断如果有重复的节点 不会增加
	while (_node)
	{
		if (FindNote(_node->name))
		{
			;
		}
		else
		{
			ValidNode(_node);
		}
			_node = _node->Next;
	}
	
	/*while (_node)
	{
		if (0 == node)
		{
			node = (PNode)malloc(sizeof(Node));
			nodeHead = node;
			memset(node,0,sizeof(Node));
			memcpy(node->name,_node->name,_node->nameLen);
			node->nameLen = _node->nameLen;
			while (_node->TableHead)
			{
				AddNodeTable(dynamicMem(_node->TableHead->Tabletype),_node->TableHead->TabletypeLen,dynamicMem(_node->TableHead->Tablename)\
					,_node->TableHead->Tablelen,dynamicMem(_node->TableHead->TableData),_node->TableHead->TableDataLen);
				_node->TableHead = _node->TableHead->Next;
			}
			AddValidElement(_node->ElementHead);
		}
		else
		{
			while (node && 0 != node->Next)
				node = node->Next;
			node->Next = (PNode)malloc(sizeof(Node));
			memset(node->Next,0,sizeof(Node));
			node->Next->Prev = node;
			node = node->Next;
			memcpy(node->name,_node->name,_node->nameLen);
			node->nameLen = _node->nameLen;
			while (_node->TableHead)
			{
				AddNodeTable(dynamicMem(_node->TableHead->Tabletype),_node->TableHead->TabletypeLen,dynamicMem(_node->TableHead->Tablename)\
					,_node->TableHead->Tablelen,dynamicMem(_node->TableHead->TableData),_node->TableHead->TableDataLen);
				_node->TableHead = _node->TableHead->Next;
			}
			AddValidElement(_node->ElementHead);
		}
		_node = _node->Next;
	}*/
	return true;
}
bool TestXML::AddValidElement(PElement _element)
{
	if (0 == node || 0 == _element)
		return false;
	while (_element)
	{
		if (0 == node->ElementHead)
		{
			node->ElementHead = (PElement)malloc(sizeof(Element));
			memset(node->ElementHead,0,sizeof(Element));
			memcpy(node->ElementHead->name,_element->name,_element->nameLen);
			node->ElementHead->nameLen = _element->nameLen;
			PTable _table = _element->TableHead;
			while (_table)//拷贝标签
			{
				AddElementTable(dynamicMem(_table->Tabletype),_table->TabletypeLen,_table->Tablename,_table->Tablelen\
					,dynamicMem(_table->TableData),_table->TableDataLen);
				_table = _table->Next;
			}
			PNodeDataInfo nodedatainfo = _element->NodeDataHead;
			while (nodedatainfo)//拷贝数据
			{
				AddElementData(nodedatainfo->Dataname,nodedatainfo->DatanameLen,dynamicMem(nodedatainfo->Data),nodedatainfo->DataLen);
				PTable ptable = nodedatainfo->DataTable;
				while (ptable)
				{
					AddElementDataTable(dynamicMem(ptable->Tabletype),ptable->TabletypeLen,dynamicMem(ptable->Tablename),ptable->Tablelen,dynamicMem(ptable->TableData),ptable->TableDataLen);
					ptable = ptable->Next;
				}
				nodedatainfo = nodedatainfo->Next;
			}
			node->Element = node->ElementHead;
		}
		else
		{
			while (node->Element && 0 != node->Element->Next)
				node->Element = node->Element->Next;
			node->Element->Next = (PElement)malloc(sizeof(Element));
			memset(node->Element->Next,0,sizeof(Element));
			node->Element->Next->Prev = node->Element;
			node->Element = node->Element->Next;
			memcpy(node->Element->name,_element->name,_element->nameLen);
			node->Element->nameLen = _element->nameLen;
			PTable _table = _element->TableHead;
			while (_table)//拷贝标签
			{
				AddElementTable(dynamicMem(_table->Tabletype),_table->TabletypeLen,_table->Tablename,_table->Tablelen\
					,dynamicMem(_table->TableData),_table->TableDataLen);
				_table = _table->Next;
			}
			PNodeDataInfo nodedatainfo = _element->NodeDataHead;
			while (nodedatainfo)//拷贝数据
			{
				AddElementData(nodedatainfo->Dataname,nodedatainfo->DatanameLen,dynamicMem(nodedatainfo->Data),nodedatainfo->DataLen);
				PTable ptable = nodedatainfo->DataTable;
				while (ptable)
				{
					AddElementDataTable(dynamicMem(ptable->Tabletype),ptable->TabletypeLen,dynamicMem(ptable->Tablename),ptable->Tablelen,dynamicMem(ptable->TableData),ptable->TableDataLen);
					ptable = ptable->Next;
				}
				nodedatainfo = nodedatainfo->Next;
			}
		}
		_element = _element->Next;
	}
	return true;
}
char* TestXML::dynamicMem(void *buffer)
{
	if (0 == buffer)
		return 0;
	int nlen = strlen((char*)buffer);
	if (0 == nlen)
		return 0;
	char *buff = (char*)malloc(nlen + 1);
	memset(buff,0,nlen + 1);
	memcpy(buff,(char*)buffer,nlen);
	return buff;
}
// bool TestXML::AddNodeData(char *NodeData,int NodeDataLen)
// {
// 	if (0 == node)
// 		return false;
// 	if (0 == NodeData || 0 >= NodeDataLen)
// 		return false;
// 	if (0 == node->NodeData)
// 	{
// 		node->NodeData = (PNodeDataInfo)malloc(sizeof(NodeDataInfo));
// 		node->NodeData->Data = NodeData;
// 		node->NodeData->DataLen = NodeDataLen;
// 		node->NodeData->Next = 0;
// 		return true;
// 	}
// 	PNodeDataInfo nodedata = node->NodeData;
// 	while (0 != nodedata->Next)
// 		nodedata = nodedata->Next;
// 	nodedata->Next = (PNodeDataInfo)malloc(sizeof(NodeDataInfo));
// 	nodedata->Next->Data = NodeData;
// 	nodedata->Next->DataLen = NodeDataLen;
// 	nodedata->Next->Next = 0;
// 	return true;
// }

bool TestXML::AddElement(char *Elename,int ElenameLen)
{
	if (0 == node)
		return false;
	if (0 == Elename || 0 >= ElenameLen)
		return false;
	if (FindElement(Elename))
		return false;
	if (0 == node->Element)
	{
		node->Element = (PElement)malloc(sizeof(Element));
		memset(node->Element,0,sizeof(Element));
		memcpy(node->Element->name,Elename,ElenameLen);
		node->Element->nameLen = ElenameLen;
		node->ElementHead = node->Element;
		return true;
	}
	while (node->Element && 0 != node->Element->Next)
		node->Element = node->Element->Next;
	node->Element->Next = (PElement)malloc(sizeof(Element));
	memset(node->Element->Next,0,sizeof(Element));
	node->Element->Next->Prev = node->Element;
	node->Element = node->Element->Next;
	memcpy(node->Element->name,Elename,ElenameLen);
	node->Element->nameLen = ElenameLen;
	return true;
}
bool TestXML::AddElementTable(char *EleTabletype,int EleTabletypeLen,char *EleTablename,int EleTableLen,char *EleTableData,int EleTableDataLen)
{
	if (0 == node)
		return false;
	if (0 == node->Element)
		return false;
	if ((0 == EleTabletype && 0 == EleTablename && 0 == EleTableData) || (0 >= EleTabletypeLen && 0 >= EleTableLen && 0 >= EleTableDataLen))
		return false;
	if (0 == node->Element->TableHead)
	{
		node->Element->TableHead = (PTable)malloc(sizeof(Table));
		node->Element->TableHead->Tabletype = EleTabletype;
		node->Element->TableHead->TabletypeLen = EleTabletypeLen;
		node->Element->TableHead->Tablename = EleTablename;
		node->Element->TableHead->Tablelen = EleTableLen;
		node->Element->TableHead->TableData = EleTableData;
		node->Element->TableHead->TableDataLen = EleTableDataLen;
		node->Element->TableHead->Next = 0;
		node->Element->table =  node->Element->TableHead;
		return true;
	}
	while (0 != node->Element->table->Next)
		node->Element->table = node->Element->table->Next;
	node->Element->table->Next = (PTable)malloc(sizeof(Table));
	node->Element->table = node->Element->table->Next;
	node->Element->table->Tabletype = EleTabletype;
	node->Element->table->TabletypeLen = EleTabletypeLen;
	node->Element->table->Tablename = EleTablename;
	node->Element->table->Tablelen = EleTableLen;
	node->Element->table->TableData = EleTableData;
	node->Element->table->TableDataLen = EleTableDataLen;
	node->Element->table->Next = 0;
	return true;
}
bool TestXML::AddElementData(char *ElaDataname,int ElaDatanameLen,char *EleData,int EleDataLen)
{
	if (0 == node)
		return false;
	if (0 == node->Element)
		return false;
	if (0 == ElaDataname || 0 >= ElaDatanameLen || 0 == EleData || 0 >= EleDataLen)
		return false;
	if (0 == node->Element->NodeData)
	{
		node->Element->NodeData = (PNodeDataInfo)malloc(sizeof(NodeDataInfo));
		memset(node->Element->NodeData,0,sizeof(NodeDataInfo));
		memcpy(node->Element->NodeData->Dataname,ElaDataname,ElaDatanameLen);
		node->Element->NodeData->DatanameLen = ElaDatanameLen;
		node->Element->NodeData->Data = EleData;
		node->Element->NodeData->DataLen = EleDataLen;
		node->Element->NodeDataHead = node->Element->NodeData;
		return true;
	}
	PNodeDataInfo eleDataInfo = node->Element->NodeData;
	while (0 != eleDataInfo->Next)
		eleDataInfo = eleDataInfo->Next;
	eleDataInfo->Next = (PNodeDataInfo)malloc(sizeof(NodeDataInfo));
	memset(eleDataInfo->Next,0,sizeof(NodeDataInfo));
	eleDataInfo = eleDataInfo->Next;
	memcpy(eleDataInfo->Dataname,ElaDataname,ElaDatanameLen);
	eleDataInfo->DatanameLen = ElaDatanameLen;
	eleDataInfo->Data = EleData;
	eleDataInfo->DataLen = EleDataLen;
	node->Element->NodeData = eleDataInfo;
	return true;
}
bool TestXML::AddElementDataTable(char *DataTabletype,int DataTabletypeLen,char *DataTablename,int DataTableLen,char *DataTableData,int DataTableDataLen)
{
	if (0 == node)
		return false;
	if (0 == node->Element)
		return false;
	if (0 == node->Element->NodeData)
		return false;
	if ((0 == DataTabletype && 0 >= DataTablename && 0 == DataTableData) || (0 >= DataTabletypeLen && 0 >= DataTableLen && 0 >= DataTableDataLen))
		return false;
	
	if (0 == node->Element->NodeData->DataTable)
	{
		node->Element->NodeData->DataTable = (PTable)malloc(sizeof(Table));
		PTable datatable = node->Element->NodeData->DataTable;
		datatable->Tabletype = DataTabletype;
		datatable->TabletypeLen = DataTabletypeLen;
		datatable->Tablename = DataTablename;
		datatable->Tablelen = DataTableLen;
		datatable->TableData = DataTableData;
		datatable->TableDataLen = DataTableDataLen;
		datatable->Next = 0;
		return true;
	}
	
	while (0 != node->Element->NodeData->DataTable->Next)
		node->Element->NodeData->DataTable = node->Element->NodeData->DataTable->Next;
	node->Element->NodeData->DataTable->Next = (PTable)malloc(sizeof(Table));
	node->Element->NodeData->DataTable = node->Element->NodeData->DataTable->Next;
	node->Element->NodeData->DataTable->Tabletype = DataTabletype;
	node->Element->NodeData->DataTable->TabletypeLen = DataTableDataLen;
	node->Element->NodeData->DataTable->Tablename = DataTablename;
	node->Element->NodeData->DataTable->Tablelen = DataTableLen;
	node->Element->NodeData->DataTable->TableData = DataTableData;
	node->Element->NodeData->DataTable->TableDataLen = DataTableDataLen;
	node->Element->NodeData->DataTable->Next = 0;
	return true;
}

int TestXML::GenerateElement(PElement Element,char* OutInfo)
{
	char *buffer = OutInfo;
	int nLen = 0;

	if (Element)
	{
		*(buffer + nLen) = '<';
		++nLen;
		memcpy(buffer + nLen,Element->name,Element->nameLen);
		nLen += Element->nameLen;
		if (Element->TableHead && (0 < Element->TableHead->TabletypeLen))//增加标签信息
		{
			*(buffer + nLen) = ' ';
			++nLen;
			memcpy(buffer + nLen,Element->TableHead->Tabletype,Element->TableHead->TabletypeLen);
			nLen += Element->TableHead->TabletypeLen;
		}
		if (Element->TableHead && (0 < Element->TableHead->Tablelen))
		{
			*(buffer + nLen) = ' ';
			++nLen;
			memcpy(buffer + nLen,Element->TableHead->Tablename,Element->TableHead->Tablelen);
			nLen += Element->TableHead->Tablelen;

		}
		if (Element->TableHead && (0 < Element->TableHead->TableDataLen))
		{
			memcpy(buffer + nLen,"=\"",strlen("=\""));
			nLen += strlen("=\"");
			memcpy(buffer + nLen,Element->TableHead->TableData,Element->TableHead->TableDataLen);
			nLen += Element->TableHead->TableDataLen;
			*(buffer + nLen) = '\"';
			++nLen;
		}
		*(buffer + nLen) = '>';
		++nLen;
		//增加文本信息
		PNodeDataInfo eledataInfo = Element->NodeDataHead;
		while(eledataInfo)
		{
			*(buffer + nLen) = 10;
			++nLen;
			*(buffer + nLen) = 9;
			++nLen;
			*(buffer + nLen) = 9;
			++nLen;
			memcpy(buffer + nLen,"<",nLen);
			nLen += strlen("<");
			memcpy(buffer + nLen,eledataInfo->Dataname,eledataInfo->DatanameLen);
			nLen += eledataInfo->DatanameLen;
			PTable datatable = eledataInfo->DataTable;
			if (datatable && (0 < datatable->TabletypeLen))
			{
				*(buffer + nLen) = ' ';
				++nLen;
				memcpy(buffer + nLen,datatable->Tabletype,datatable->TabletypeLen);
				nLen += Element->NodeData->DataTable->TabletypeLen;
			}
			if (datatable && (0 < datatable->Tablelen))
			{
				*(buffer + nLen) = ' ';
				++nLen;
				memcpy(buffer + nLen,datatable->Tablename,datatable->Tablelen);
				nLen += datatable->Tablelen;
			}
			if (datatable && (0 < datatable->TableDataLen))
			{
				memcpy(buffer + nLen,"=\"",strlen("=\""));
				nLen += strlen("=\"");
				memcpy(buffer + nLen,datatable->TableData,datatable->TableDataLen);
				nLen += datatable->TableDataLen;
				*(buffer + nLen) = '\"';
				++nLen;
			}
			memcpy(buffer + nLen,">",nLen);
			nLen += strlen(">");
			//文本数据
			memcpy(buffer + nLen,eledataInfo->Data,eledataInfo->DataLen);
			nLen += eledataInfo->DataLen;
			memcpy(buffer + nLen,"</",strlen("</"));
			nLen += strlen("</");
			memcpy(buffer + nLen,eledataInfo->Dataname,eledataInfo->DatanameLen);
			nLen += eledataInfo->DatanameLen;
			*(buffer + nLen) = '>';
			++nLen;
			//Element->NodeData = Element->NodeData->Next;
			eledataInfo = eledataInfo->Next;
		}
		*(buffer + nLen) = 10;
		++nLen;
		*(buffer + nLen) = 9;
		++nLen;
		memcpy(buffer + nLen,"</",strlen("</"));
		nLen += strlen("</");
		memcpy(buffer + nLen,Element->name,Element->nameLen);
		nLen += Element->nameLen;
		*(buffer + nLen) = '>';
		++nLen;
	}
	return nLen;
}

int TestXML::GenerateNode(PNode nodeInfo,char* OutInfo)
{
	char *buffer = OutInfo;
	int nLen = 0;
	*(buffer + nLen) = '<'; 
	++nLen;
	memcpy(buffer + nLen,nodeInfo->name,nodeInfo->nameLen);
	nLen += nodeInfo->nameLen;
	if (nodeInfo->TableHead && (0 < nodeInfo->TableHead->TabletypeLen))//增加标签信息
	{
		*(buffer + nLen) = ' ';
		++nLen;
		memcpy(buffer + nLen,nodeInfo->TableHead->Tabletype,nodeInfo->TableHead->TabletypeLen);
		nLen += nodeInfo->TableHead->TabletypeLen;
	}
	if (nodeInfo->TableHead && (0 < nodeInfo->TableHead->Tablelen))
	{
		*(buffer + nLen) = ' ';
		++nLen;
		memcpy(buffer + nLen,nodeInfo->TableHead->Tablename,nodeInfo->TableHead->Tablelen);
		nLen += nodeInfo->TableHead->Tablelen;
		
	}
	if (nodeInfo->TableHead && (0 < nodeInfo->TableHead->TableDataLen))
	{
		memcpy(buffer + nLen,"=\"",strlen("=\""));
		nLen += strlen("=\"");
		memcpy(buffer + nLen,nodeInfo->TableHead->TableData,nodeInfo->TableHead->TableDataLen);
		nLen += nodeInfo->TableHead->TableDataLen;
		*(buffer + nLen) = '\"';
		++nLen;
	}
	memcpy(buffer + nLen,">",nLen);
	nLen += strlen(">");

	PElement element = nodeInfo->ElementHead;
	//增加元素信息
	while (element)
	{
		*(buffer + nLen) = 10;
		++nLen;
		*(buffer + nLen) = 9;
		++nLen;
		int nEleLen = 0;
		nEleLen = GenerateElement(element,buffer + nLen);
		nLen += nEleLen;
		element = element->Next;
	}


	*(buffer + nLen) = 10;
	++nLen;
	memcpy(buffer + nLen,"</",strlen("</"));
	nLen += strlen("</");
	memcpy(buffer + nLen,nodeInfo->name,nodeInfo->nameLen);
	nLen += nodeInfo->nameLen;
	*(buffer + nLen) = '>';
	++nLen;
	return nLen;
}
bool TestXML::CreateXML()
{
	if (0 == headInfo || 0 == nodeHead)
		return false;
	char *buffer = (char*)malloc(sizeof(char) * XMLBUFFER);
	memset(buffer,0,sizeof(char) * XMLBUFFER);
	int nLen = 0;
	//增加头信息
	PHeadInfo headinfo = headInfo;
	while (headinfo)
	{
		memcpy(buffer + nLen,headinfo->HeadData,headinfo->HeadDataLen);
		nLen += headinfo->HeadDataLen;
		*(buffer + nLen) = 10; //换行
		++nLen;
		headinfo = headinfo->Next;
	}
	//增加节点信息
	PNode nodeinfo = nodeHead;
	char *nodestr = (char*)malloc(1024 * 1024);
	while (nodeinfo)
	{
		memset(nodestr,0,1024 * 1024);
		int nNodeLen = GenerateNode(nodeinfo,nodestr);
		memcpy(buffer + nLen,nodestr,nNodeLen);
		nLen += nNodeLen;
		nodeinfo = nodeinfo->Next;
		*(buffer + nLen) = 10; //换行
		++nLen;
	}
	if (XMLData)
		free(XMLData);
	XMLData = (char*)malloc(nLen);
	memset(XMLData,0,nLen);
	memcpy(XMLData,buffer,nLen);
	XMLDataLen = nLen;
	free(buffer);
	free(nodestr);
	return true;

}
bool TestXML::CreateXMLFile(char *Filename)
{
	if (!CreateXML())
		return false;
	if ((Generatefile = fopen(Filename,"w")) == NULL)
		return false;
	int nLen = XMLDataLen;
	int nWriLen = 0;
	while (0 < nLen)
	{
		if (4096 <= nLen)
		{
			fwrite(XMLData + nWriLen,1,4096,Generatefile);
			nWriLen += 4096;
			nLen -= 4096;
		}
		else
		{
			fwrite(XMLData + nWriLen,1,nLen,Generatefile);
			nWriLen += nLen;
			nLen -= nLen;
		}
	}
	fclose(Generatefile);
	return true;
}
char *TestXML::GetXMLData()
{
	return XMLData;
}
int TestXML::GetXMLDataLen()
{
	return XMLDataLen;
}
PHeadInfo TestXML::CheckHeadInfo()
{
	return headInfo;
}








TestAnalyXML::TestAnalyXML():headInfo(0),XMLData(0),XMLDataLen(0),nodeHead(0),node(0)
{

}
TestAnalyXML::~TestAnalyXML()
{
	AnalyFreeHeadInfo();
	AnalyFreeAllNode();
}
PNode TestAnalyXML::AnalyXML(char *XmlData,bool nfile)
{
	if (0 == XmlData)
		return 0;
	PNode _node = AnalyFile(XmlData,nfile);
	return _node;
}
PNode TestAnalyXML::AnalyFile(char *XmlData,bool nfile)
{
	if (0 == XmlData)
		return 0;
	int nLen = 0;
	if (nfile)
	{
		if ((Generatefile = fopen(XmlData,"r")) == NULL)
			return 0;
		if (XMLData)
			free(XMLData);
		fseek(Generatefile,0,SEEK_END);
		nLen = ftell (Generatefile);
		XMLData = (char*)malloc(nLen);
		memset(XMLData,0,nLen);
		fseek(Generatefile,0,SEEK_SET);
		fread(XMLData,1,nLen,Generatefile);
		fclose(Generatefile);
	}
	else
	{
		nLen = strlen(XmlData);
		XMLData = (char*)malloc(nLen);
		memset(XMLData,0,nLen);
		memcpy(XMLData,XmlData,nLen);
	}
	XMLDataLen = nLen;
	int nSeek = AnalyHeadInfo(XMLData);
	PNode _node = AnalyData(XMLData + nSeek);
	return _node;
}
PNode TestAnalyXML::AnalyData(const char *XmlData)
{
	if (0 == XmlData)
		return 0;
	int nLen = strlen(XmlData);
	PNode _node = AnalyNodeName(XmlData);
	return _node;
}
PNode TestAnalyXML::AnalyNodeName(const char *XmlData)
{
	if (0 == XmlData)
		return 0;
	int nSeek = 0;
	char nodeTable[1024] = {0};//解析节点标签
	int nNodeDataLen = 0;
	int nXmlLen = XMLDataLen;
	while (0 <= nSeek)
	{

		int nbeLen = FindData(XmlData + nSeek,"<",XMLDataLen - nSeek);
		int nenLen = FindData(XmlData + nSeek,">",XMLDataLen - nSeek);
		int ncopyLen = (nenLen - nbeLen);
		if (0 > nenLen)
			return nodeHead;
		nSeek += (nbeLen + 1);
		memset(nodeTable,0,sizeof(nodeTable));
		memcpy(nodeTable,XmlData + nSeek,ncopyLen);
		if (0 == nodeHead)
		{
			nodeHead = (PNode)malloc(sizeof(Node));
			memset(nodeHead,0,sizeof(Node));
			//解析标签
			nodeHead->TableHead = AnalyTable(nodeTable);
			//解析节点名称
			if (nodeHead->TableHead && (nodeHead->TableHead->Tabletype || nodeHead->TableHead->Tablename))
			{
				nenLen = FindData(nodeTable," ",ncopyLen);
				memcpy(nodeHead->name,nodeTable,nenLen);
				nodeHead->nameLen = nenLen;
			}
			else if (-1 < FindData(nodeTable,"\"=",ncopyLen))
			{
				nenLen = FindData(nodeTable,"\"=",ncopyLen);
				memcpy(nodeHead->name,nodeTable,nenLen);
				nodeHead->nameLen = nenLen;
			}
			else
			{
				nenLen = FindData(nodeTable,">",ncopyLen);
				memcpy(nodeHead->name,nodeTable,nenLen);
				nodeHead->nameLen = nenLen;
			}
			//保存节点数据长度
			nSeek += ncopyLen;
			sprintf(nodeTable,"</%s>",nodeHead->name);
			nenLen = FindData(XmlData + nSeek,nodeTable,nXmlLen - nSeek);
			nodeHead->ElementHead = nodeHead->Element = AnalyElement(XmlData + nSeek,nenLen);
			if (nodeHead->Element)
			{
				while (0 != nodeHead->Element->Next)//带头的链表都把身体指向最后一节
					nodeHead->Element = nodeHead->Element->Next;
			}
			node = nodeHead;
			nSeek += (strlen(nodeTable) + nenLen);
		}
		else
		{
			while (0 != node->Next)
				node = node->Next;
			node->Next = (PNode)malloc(sizeof(Node));
			memset(node->Next,0,sizeof(Node));
			node->Next->TableHead = AnalyTable(nodeTable);
			if (node->Next->TableHead && (node->Next->TableHead->Tabletype || node->Next->TableHead->Tablename))
			{
				nenLen = FindData(nodeTable," ",ncopyLen);
				memcpy(node->Next->name,nodeTable,nenLen);
				node->Next->nameLen = nenLen;
			}
			else if (-1 < FindData(nodeTable,"\"=",ncopyLen))
			{
				nenLen = FindData(nodeTable,"\"=",ncopyLen);
				memcpy(node->Next->name,nodeTable,nenLen);
				node->Next->nameLen = nenLen;
			}
			else
			{
				nenLen = FindData(nodeTable,">",ncopyLen);
				memcpy(node->Next->name,nodeTable,nenLen);
				node->Next->nameLen = nenLen;
			}
			//保存节点数据长度
			nSeek += ncopyLen;
			sprintf(nodeTable,"</%s>",node->Next->name);
			nenLen = FindData(XmlData + nSeek,nodeTable,nXmlLen - nSeek);
			node->Next->ElementHead = node->Next->Element = AnalyElement(XmlData + nSeek,nenLen);
			if (node->Next->Element)
			{
				while (0 != node->Next->Element->Next)//带头的链表都把身体指向最后一节
					node->Next->Element = node->Next->Element->Next;
			}
			node->Next->Prev = node;
			node = node->Next;
			nSeek += (strlen(nodeTable) + nenLen);
		}
	}
	return nodeHead;
}
PElement TestAnalyXML::AnalyElement(const char*data,int nlen)
{
	if (0 == data || 0 >= nlen)
		return 0;
	int nSeek = 0;
	PElement element = 0;
	char eleTable[1024] = {0};//解析节点标签
	const char *eleData = 0;
	while (0 <= nSeek)
	{
		int nbeLen = FindData(data + nSeek,"<",nlen - nSeek);
		int nenLen = FindData(data + nSeek,">",nlen - nSeek);
		int ncopyLen = (nenLen - nbeLen);
		if (0 > nenLen)
			return element;
		nSeek += (nbeLen + 1);
		memcpy(eleTable,data + nSeek,ncopyLen);
		if (0 == element)
		{
			element = (PElement)malloc(sizeof(Element));
			memset(element,0,sizeof(Element));
			//解析标签
			element->TableHead = AnalyTable(eleTable);
			//解析节点名称
			if (element->TableHead && (element->TableHead->Tabletype || element->TableHead->Tablename))
			{
				nenLen = FindData(eleTable," ",ncopyLen);
				memcpy(element->name,eleTable,nenLen);
				element->nameLen = nenLen;
			}
			else if (-1 < FindData(eleTable,"\"=",ncopyLen))
			{
				nenLen = FindData(eleTable,"\"=",ncopyLen);
				memcpy(element->name,eleTable,nenLen);
				element->nameLen = nenLen;
			}
			else
			{
				nenLen = FindData(eleTable,">",ncopyLen);
				memcpy(element->name,eleTable,nenLen);
				element->nameLen = nenLen;
			}
			//保存节点数据长度
			nSeek += ncopyLen;
			sprintf(eleTable,"</%s>",element->name);
			nenLen = FindData(data + nSeek,eleTable,nlen - nSeek);
			element->NodeDataHead = element->NodeData = AnalyEleDataInfo(data + nSeek,nenLen);
			if (element->NodeData)
			{
				while (0 != element->NodeData->Next)//带头的链表都把身体指向最后一节
					element->NodeData = element->NodeData->Next;
			}
			
			nSeek += (strlen(eleTable) + nenLen);
		}
		else
		{
			PElement _element = element;
			while (0 != _element->Next)
				_element = _element->Next;
			_element->Next = (PElement)malloc(sizeof(Element));
			memset(_element->Next,0,sizeof(Element));
			_element = _element->Next;
			//解析标签
			_element->TableHead = AnalyTable(eleTable);
			//解析节点名称
			if (_element->TableHead && (_element->TableHead->Tabletype || _element->TableHead->Tablename))
			{
				nenLen = FindData(eleTable," ",ncopyLen);
				memcpy(_element->name,eleTable,nenLen);
				_element->nameLen = nenLen;
			}
			else if (-1 < FindData(eleTable,"\"=",ncopyLen))
			{
				nenLen = FindData(eleTable,"\"=",ncopyLen);
				memcpy(_element->name,eleTable,nenLen);
				_element->nameLen = nenLen;
			}
			else
			{
				nenLen = FindData(eleTable,">",ncopyLen);
				memcpy(_element->name,eleTable,nenLen);
				_element->nameLen = nenLen;
			}
			//保存节点数据长度
			nSeek += ncopyLen;
			sprintf(eleTable,"</%s>",_element->name);
			nenLen = FindData(data + nSeek,eleTable,nlen - nSeek);
			_element->NodeDataHead = _element->NodeData = AnalyEleDataInfo(data + nSeek,nenLen);
			if (_element->NodeData)
			{
				while (0 != _element->NodeData->Next)//带头的链表都把身体指向最后一节
					_element->NodeData = _element->NodeData->Next;
			}
			nSeek += (strlen(eleTable) + nenLen);
		}
	}
	return element;
}
PNodeDataInfo TestAnalyXML::AnalyEleDataInfo(const char*data,int nlen)
{
	if (0 == data || 0 >= nlen)
		return 0;
	int nSeek = 0;
	char dataTable[1024] = {0};//解析数据标签
	const char *eleData = 0;
	PNodeDataInfo nodedata = 0;
	int dataLen = 0;
	while (0 <= nSeek)
	{
		int nbeLen = FindData(data + nSeek,"<",nlen - nSeek);
		int nenLen = FindData(data + nSeek,">",nlen - nSeek);
		int ncopyLen = (nenLen - nbeLen);
		if (0 > nenLen)
			return nodedata;
		nSeek += (nbeLen + 1);
		memcpy(dataTable,data + nSeek,ncopyLen);
		if (0 == nodedata)
		{
			nodedata = (PNodeDataInfo)malloc(sizeof(NodeDataInfo));
			memset(nodedata,0,sizeof(NodeDataInfo));
			//解析标签
			nodedata->DataTable = AnalyTable(dataTable);
			//解析节点名称
			if (nodedata->DataTable && (nodedata->DataTable->Tabletype || nodedata->DataTable->Tablename))
			{
				nenLen = FindData(dataTable," ",ncopyLen);
				memcpy(nodedata->Dataname,dataTable,nenLen);
				nodedata->DatanameLen = nenLen;
			}
			else if (-1 < FindData(dataTable,"\"=",ncopyLen))
			{
				nenLen = FindData(dataTable,"\"=",ncopyLen);
				memcpy(nodedata->Dataname,dataTable,nenLen);
				nodedata->DatanameLen = nenLen;
			}
			else
			{
				nenLen = FindData(dataTable,">",ncopyLen);
				memcpy(nodedata->Dataname,dataTable,nenLen);
				nodedata->DatanameLen = nenLen;
			}
			//保存节点数据长度
			nSeek += ncopyLen; 
			sprintf(dataTable,"</%s>",nodedata->Dataname);
			nenLen = FindData(data + nSeek,dataTable,nlen - nSeek);
			nodedata->Data = (char*)malloc(nenLen + 1);
			memset(nodedata->Data,0,nenLen + 1);
			memcpy(nodedata->Data,data + nSeek,nenLen);
			nodedata->DataLen = nenLen;
			nSeek += (strlen(dataTable) + nenLen);
		}
		else
		{
			PNodeDataInfo _nodedata = nodedata;
			while (0 != _nodedata->Next)
				_nodedata = _nodedata->Next;
			_nodedata->Next = (PNodeDataInfo)malloc(sizeof(NodeDataInfo));
			memset(_nodedata->Next,0,sizeof(NodeDataInfo));
			_nodedata = _nodedata->Next;
			//解析标签
			_nodedata->DataTable = AnalyTable(dataTable);
			//解析节点名称
			if (_nodedata->DataTable && (_nodedata->DataTable->Tabletype || _nodedata->DataTable->Tablename))
			{
				nenLen = FindData(dataTable," ",ncopyLen);
				memcpy(_nodedata->Dataname,dataTable,nenLen);
				_nodedata->DatanameLen = nenLen;
			}
			else if (-1 < FindData(dataTable,"\"=",ncopyLen))
			{
				nenLen = FindData(dataTable,"\"=",ncopyLen);
				memcpy(_nodedata->Dataname,dataTable,nenLen);
				_nodedata->DatanameLen = nenLen;
			}
			else
			{
				nenLen = FindData(dataTable,">",ncopyLen);
				memcpy(_nodedata->Dataname,dataTable,nenLen);
				_nodedata->DatanameLen = nenLen;
			}
			//保存节点数据长度
			nSeek += ncopyLen; 
			sprintf(dataTable,"</%s>",_nodedata->Dataname);
			nenLen = FindData(data + nSeek,dataTable,nlen - nSeek);
			_nodedata->Data = (char*)malloc(nenLen + 1);
			memset(_nodedata->Data,0,nenLen + 1);
			memcpy(_nodedata->Data,data + nSeek,nenLen);
			_nodedata->DataLen = nenLen;
			nSeek += (strlen(dataTable) + nenLen);
		}
	}
	return nodedata;
}
PTable TestAnalyXML::AnalyTable(const char *XmlData)
{
	if (0 == XmlData)
		return 0;
	int nspaceNum = Findnumber(XmlData," ",strlen(XmlData));//首先获取到多少个空格来算出有几个有效标签数据
	int nequalNum = FindData(XmlData,"=\"",strlen(XmlData));//获取到等号
	int nSeek = 0;
	int nLen = 0;
	//先用临时变量保存数据 如果数据都为空那么不分配内存
	char *Tabletype = 0,*Tablename = 0,*TableData = 0;
	int TabletypeLen = 0,Tablelen = 0,TableDataLen = 0;
	if (0 < nspaceNum)
	{
		if (2 == nspaceNum)
		{
			nSeek = FindData(XmlData," ",strlen(XmlData));//第一条为名称不在标签范围内
			++nSeek;
			nLen = FindData(XmlData + nSeek," ",strlen(XmlData));//标签类型
			Tabletype = (char*)malloc(nLen + 1);
			memset(Tabletype,0,nLen + 1);
			TabletypeLen = nLen;
			memcpy(Tabletype,XmlData + nSeek,nLen);
			nSeek += (nLen + 1);
		}
		if (1 == nspaceNum)
		{
			nSeek = FindData(XmlData," ",strlen(XmlData));//第一条为名称不在标签范围内
			++nSeek;
		}
	}
	if (-1 < nequalNum)//标签名
	{
		nLen = FindData(XmlData + nSeek,"=\"",strlen(XmlData));
		Tablename = (char*)malloc(nLen + 1);
		memset(Tablename,0,nLen + 1);
		Tablelen = nLen;
		memcpy(Tablename,XmlData + nSeek,nLen);
		nSeek += (nLen + 2);
		//标签数据
		nLen = FindData(XmlData + nSeek,"\">",strlen(XmlData) - nSeek);
		TableData = (char*)malloc(nLen + 1);
		memset(TableData,0,nLen + 1);
		TableDataLen = nLen;
		memcpy(TableData,XmlData + nSeek,nLen);
	}
	PTable table = 0;//(PTable)malloc(sizeof(Table));
	if (0 != TabletypeLen || 0 != Tablelen || 0 != TableDataLen)
	{
		table = (PTable)malloc(sizeof(Table));
		memset(table,0,sizeof(Table));
		table->Tabletype = Tabletype;
		table->TabletypeLen = TabletypeLen;
		table->Tablename = Tablename;
		table->Tablelen = Tablelen;
		table->TableData = TableData;
		table->TableDataLen = TableDataLen;
	}
	return table;
}

int TestAnalyXML::AnalyHeadInfo(const char *XmlData)
{
	if (0 == XmlData)
		return 0;
	int nSeek = 0;
	while (0 <= nSeek)
	{
		int nbeLen = FindData(XmlData + nSeek,"<?",XMLDataLen);
		int nenLen = FindData(XmlData + nSeek,"?>",XMLDataLen);
		int ncopyLen = nenLen - nbeLen + strlen("?>");
		if (0 > nenLen)
			return nSeek;
		if (0 == headInfo)
		{
			headInfo = (PHeadInfo)malloc(sizeof(HeadInfo));
			memset(headInfo,0,sizeof(HeadInfo));
			headInfo->HeadData = (char *)malloc(ncopyLen + 1);
			memset(headInfo->HeadData,0,ncopyLen + 1);
			memcpy(headInfo->HeadData,XmlData + nbeLen,ncopyLen);
			headInfo->HeadDataLen = ncopyLen;
			headInfo->Next = 0;
		}
		else
		{
			if (FindHeadInfo((char *)XmlData + (nSeek + nbeLen),ncopyLen))
				return (nSeek += (nenLen + strlen("?>")));
			PHeadInfo headinfo = headInfo;
			while (0 != headinfo->Next)
				headinfo = headinfo->Next;
			headinfo->Next = (PHeadInfo)malloc(sizeof(HeadInfo));
			memset(headinfo->Next,0,sizeof(HeadInfo));
			headinfo->Next->HeadData = (char *)malloc(ncopyLen + 1);
			memset(headInfo->HeadData,0,ncopyLen + 1);
			memcpy(headinfo->Next->HeadData,XmlData + (nSeek + nbeLen),ncopyLen);
			headinfo->Next->HeadDataLen = ncopyLen;
			headinfo->Next->Next = 0;
		}
		nSeek += (nenLen + strlen("?>"));
	}
	return nSeek;
}
int TestAnalyXML::Findnumber(const char *srcdata,const char *seekdata,int srclen)
{
	const char* psrc = srcdata;
	const char* pseek = seekdata;
	int nLen = strlen(pseek);
	int FindLen = 0;
	int nNum = 0;
	for (;FindLen < srclen;)
	{	
		bool bequal = true;
		for (int it = 0;bequal && it < nLen;it++)
		{
			if (*(psrc + FindLen) == *(pseek + it))
				bequal = true;
			else
				bequal = false;
			++FindLen;
		}
		if (bequal)
		{	
			++nNum;	
		}
	}
	return nNum;
}
int TestAnalyXML::FindData(const char *srcdata,const char *seekdata,int srclen)
{
	const char* psrc = srcdata;
	const char* pseek = seekdata;
	int nLen = strlen(pseek);
	int FindLen = 0;

	for (;FindLen < srclen;)
	{	
		bool bequal = true;
		for (int it = 0;bequal && it < nLen;it++)
		{
			if (*(psrc + FindLen) == *(pseek + it))
				bequal = true;
			else
				bequal = false;
			++FindLen;
		}
		if (bequal)
		{	
			FindLen -= nLen;
			return FindLen;
		}

	}
	return -1;
}
PHeadInfo TestAnalyXML::GetHeadInfo()
{
	return headInfo;
}
PNode TestAnalyXML::GetAnalyNode()
{
	return nodeHead;
}
bool TestAnalyXML::FindHeadInfo(char* HeadData,int HeadDataLen)
{
	if (0 == HeadData || 0 >= HeadDataLen)
		return true;
	PHeadInfo headinfo = headInfo;
	while (headinfo)
	{
		bool bequal = true;
		if (headinfo->HeadDataLen != HeadDataLen)
			bequal = false;
		for (int i = 0;bequal && i < HeadDataLen;i++)
		{
			if (*(headinfo->HeadData + i) == *(HeadData + i))
				bequal = true;
			else
				bequal = false;
		}
		if (bequal)
			return true;
		headinfo = headinfo->Next;
	}
	return false;
}
bool  TestAnalyXML::AnalyFreeHeadInfo()
{
	if (0 == headInfo)
		return false;
	PHeadInfo head = headInfo;
	while (head)
	{
		headInfo = headInfo->Next;
		free(head->HeadData);
		free(head);
		head = 0;
		head = headInfo;
	}
	return true;
}
bool TestAnalyXML::AnalyFreeAllNode()
{
	if (!nodeHead)
		return false;
	PNode freeNode = nodeHead;
	while (freeNode)
	{
		freeNode = AnalyFreeNode(freeNode);
	}
	nodeHead = node = 0;
	return true;
}
PNode TestAnalyXML::AnalyFreeNode(PNode freenode)
{
	if (!freenode)
		return freenode;
	PNode Node = freenode->Next;
	if (Node && freenode->ElementHead)
	{
		//首先释放元素
		PElement element = freenode->ElementHead;
		while (element)
		{
			element = AnalyFreeElement(element);
		}
	}
	if (freenode->TableHead)
	{
		AnalyFreeTable(freenode->TableHead);
	}
	freenode = 0;
	return Node;
}
PElement TestAnalyXML::AnalyFreeElement(PElement freeEle)
{
	if (!freeEle)
		return freeEle;
	//保存下一个元素
	PElement next = freeEle->Next;
	//释放数据头
	PNodeDataInfo dataHead = freeEle->NodeDataHead;
	while (dataHead)
	{
		PNodeDataInfo next = dataHead->Next;
		if (dataHead->DataTable)
			AnalyFreeTable(dataHead->DataTable);
		free(dataHead->Data);
		free(dataHead);
		dataHead = next;
	}
	//释放元素标签
	if (freeEle->TableHead)
		AnalyFreeTable(freeEle->TableHead);
	return next;
}
bool TestAnalyXML::AnalyFreeTable(PTable freeTable)
{
	if (!freeTable)
		return false;
	PTable tab = freeTable;
	while (tab)
	{
		PTable next = tab->Next;
		free(tab->TableData);
		free(tab->Tablename);
		free(tab->Tabletype);
		free(tab);
		tab = next;
	}
	return true;
}

XML函数说明:

bool		LCreateHeadInfo(char *vesion,char *encoding);
//创建一个头信息指定版本和编码格式,在不创建的情况使用默认参数1.0和UTF-8

bool		LAddHeadInfo(char *HeadData,int HeadDataLen);
//增加一个自定义信息格式为<?data?>,第二参数是数据长度

PHeadInfo	LCheckHeadInfo();
//返回当前保存的头信息

bool		LCreateNode(char *Nodename,int NodenameLen);
//清除之前所有的节点 重新第一个节点
//第一个参数 节点名称
//第二个参数 节点名称长度

bool		LAddNode(char *Nodename,int NodenameLen);
//按顺序在节点尾部增加新的节点
//第一个参数 节点名称
//第二个参数 节点名称长度

bool		LAddNodeTable(char *Tabletype,int TabletypeLen,char *Tablename,int TableLen,char *TableData,int TableDataLen);
//增加当前节点的标签信息
//第一个参数 标签类型
//第二个参数 标签类型长度
//第三个参数 标签名称
//第四个参数 标签名称长度
//第五个参数 标签数据
//第六个参数 标签数据长度
//在这三个数据中需要至少添加一中数据和数据长度(比如增加标签类型和标签类型长度),如果当前节点不需要标签信息,不需要调用这个函数

bool		LCreateElement(char *Elename,int ElenameLen);
//清除当前节点下所有的元素 创建第一个元素
//第一个参数 元素名称
//第二个参数 元素名称长度

bool		LAddElement(char *Elename,int ElenameLen);
//按顺序在当前节下元素尾部增加新的元素信息
//第一个参数 元素名称
//第二个参数 元素名称长度

bool		LAddElementTable(char *EleTabletype,int EleTabletypeLen,char *EleTablename,int EleTableLen,char *EleTableData,int EleTableDataLen);
//和节点标签用法一样

bool		LAddElementData(char *ElaDataname,int ElaDatanameLen,char *EleData,int EleDataLen);
//增加元素数据 元素节点内的数据节点
//第一个参数 元素数据名称
//第二个参数 元素数据名称长度
//第三个参数 元素数据
//第四个参数 元素数据长度

bool		LAddElementDataTable(char *DataTabletype,int DataTabletypeLen,char *DataTablename,int DataTableLen,char *DataTableData,int DataTableDataLen);
//增加元素数据标签 用法与节点相同

bool		LCreateXML();
//创建XML字符串 如果没有节点信息将会创建失败

bool		LCreateXMLFile(char *Filename);
//创建XML文件 
//第一个参数 创建文件路径加文件名称

bool		LFreeAllNode();
//释放生成类里的所有节点 默认不需要调用,释放类对象时会自动调用

PNode		LFreeNode(PNode freenode);
//释放指定节点 一般由内部函数使用
//返回下一个节点 如果没有下一个节点返回NULL
//第一个参数 节点信息

PElement	LFreeElement(PElement freeEle);
//释放指定元素
//返回下一个元素 如果没有下一个元素返回NULL
//第一个参数 元素信息

PNode		LAnalyXML(char *XmlData,bool nfile);
//解析XMl
//返回头节点信息(返回整个节点链表)
//第一个参数 可以是字符串,也可以是地址加文件名称
//第二个参数 nfile为1会按照地址加文件名称读取文件信息解析,为0按照字符串解析

PHeadInfo	LGetHeadInfo();
//获取解析到的头信息
//返回头信息

PNode       LGetAnalyNode();
//获取解析到的节点信息
//返回节点信息

bool        LAnalyToHeadInfo(PHeadInfo _node);
//解析到的头信息保存到XML生成类,并且删除原来的生成类头信息
//第一个参数 头信息

bool        LAnalyAddHeadInfo(PHeadInfo _node);
//解析到的头信息保存到XML生成类,不删除原来的生成类信息
//第一个参数 头信息

bool		LAnalyToNode(PNode _node);
//解析到的节点保存到XML生成类节点,并且删除原来的生成类节点
//第一个参数 节点信息

bool		LAnalyAddNode(PNode _node);
//解析到的节点保存到XML生成类节点, 不删除原来的生成类节点并且增加在原来节点的尾部
//第一个参数 节点信息

char *      LGetXMLData();
//获取生成的XML数据 
//特别说明:获取到的XML数据属于从核心类里拷贝出来的数据,为了保证数据的安全性由调用者来释放

下面贴上测试代码:

LkyXML lkyxml;
lkyxml.LAddHeadInfo("<?567?>",strlen("<?567?>"));
lkyxml.LCreateHeadInfo("tyu","f9");
lkyxml.LCreateHeadInfo("xml","Utf-8");
lkyxml.LAddHeadInfo("<?8910?>",strlen("<?8910?>"));
lkyxml.LCheckHeadInfo();
lkyxml.LAddNode("node1",strlen("node1"));
lkyxml.LAddNodeTable("",0,"node1Tablename",strlen("node1Tablename"),"",0);
lkyxml.LCreateElement("node1ele1",strlen("node1ele1"));
lkyxml.LAddElement("node1ele2",strlen("node1ele2"));
lkyxml.LAddElementTable("eletabletype1",strlen("eletabletype1"),"",0,"eletabledata1",strlen("eletabledata1"));
lkyxml.LAddElementData("eledataname1",strlen("eledataname1"),"eledata1",strlen("eledata1"));
lkyxml.LAddElementDataTable("eledatatype1",strlen("eledatatype1"),"",0,"",0);
lkyxml.LCreateXML();


lkyxml.LAnalyAddHeadInfo(lkyxml.LGetHeadInfo());
lkyxml.LAnalyXML("C:\\Users\\Administrator\\Desktop\\TestXML.xml",1);
lkyxml.LAnalyAddNode(lkyxml.LGetAnalyNode());
lkyxml.LCreateXMLFile("C:\\Users\\Administrator\\Desktop\\TestXML3.xml");
char *xmlData = lkyxml.LGetXMLData();

转载地址:lkyof.blog.csdn.net/article/det…

源码下载地址:download.csdn.net/download/a2…