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

放假期间在家有点无聊,前一段时间对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函数说明:

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

猜你喜欢

转载自blog.csdn.net/a29562268/article/details/78159570