放假期间在家有点无聊,前一段时间对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:[email protected]
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:[email protected]
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函数说明:
扫描二维码关注公众号,回复:
2648575 查看本文章
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();
源码下载地址:http://download.csdn.net/download/a29562268/10007709!