C/C++读写解析xml文件,写的比较简单,读写解析测试了下,定位更新等操作懒得测试了,估计有很多可以优化的,欢迎各位阅读,也欢迎来讨论
#include#include #define ERR_MES_1 "输入值不合法" #define ERR_MES_2 "打开文件失败" #define ERR_MES_3 "配置项不存在" class XmlAttribute { public: XmlAttribute(); ~XmlAttribute(); std::string m_Name; std::string m_Value; XmlAttribute *m_pNext; }; class XmlNode { public: XmlNode(); ~XmlNode(); std::string m_Name; std::string m_Value; XmlNode *m_pParent; XmlNode *m_pPrev; XmlNode *m_pNext; XmlNode *m_pChild; XmlAttribute *m_pAttribute; }; class XmlFile { public: XmlFile(); ~XmlFile(); bool ReadFile(const char *FilePathName); bool WriteFile(const char *FilePathName); bool AnalysisFile(); void LocateRoot(); bool LocateNode(XmlNode *pNode); bool LocateParent(); bool LocatePrev(); bool LocateNext(); bool LocatepChild(); XmlNode *GetCurNode(); std::string GetCurNodeName(); std::string GetCurNodevalue(); XmlAttribute *GetCurNodeAttribute(); XmlNode *AddXmlNode(XmlNode *pParent, std::string Name, std::string Value); bool UpdateXmlNode(XmlNode *pNode, std::string Name, std::string Value); void DeleteXmlNode(XmlNode *pNode); bool AddNodeAttribute(XmlNode *pNode, std::string AttributeName, std::string Attributevalue); bool UpdateNodeAttribute(XmlNode *pNode, std::string AttributeName, std::string Attributevalue); void DeleteNodeAttribute(XmlNode *pNode); void DeleteNodeAttribute(XmlNode *pNode, std::string AttributeName); friend void AnalysisXml(XmlNode *pParent, char *Buffer, long BufferSize); friend void CreateNode(XmlNode *pNode, char *pValue); friend void Trim(char *Buffer); friend void NodeToBuffer(XmlNode *pNode, char *pBuffer, int Depth); friend void DeleteNode(XmlNode *pNode); friend void DeleteAttribute(XmlAttribute *pAttribute); protected: private: char *m_pFileBuffur; XmlNode *m_pRootNode; XmlNode *m_pCurNode; FILE *m_pFileHandle; int m_LastErrCode; std::string m_LastErrMes; long m_FileSize; }; void AnalysisXml(XmlNode *pParent, char *Buffer, long BufferSize); void CreateNode(XmlNode *pNode, char *pValue); void Trim(char *Buffer); void NodeToBuffer(XmlNode *pNode, char *pBuffer, int Depth); void DeleteNode(XmlNode *pNode); void DeleteAttribute(XmlAttribute *pAttribute);
#include "xmlfile.h" #includeXmlAttribute::XmlAttribute() { m_Name = ""; m_Value = ""; m_pNext = nullptr; } XmlAttribute::~XmlAttribute() { } XmlNode::XmlNode() { m_Name = ""; m_Value = ""; m_pParent = nullptr; m_pPrev = nullptr; m_pNext = nullptr; m_pChild = nullptr; m_pAttribute = nullptr; } XmlNode::~XmlNode() { } XmlFile::XmlFile() { m_pFileBuffur = nullptr; m_pRootNode = nullptr; m_pCurNode = nullptr; m_pFileHandle = nullptr; } XmlFile::~XmlFile() { DeleteXmlNode(m_pRootNode); delete[]m_pFileBuffur; fclose(m_pFileHandle); m_pFileBuffur = nullptr; m_pRootNode = nullptr; m_pCurNode = nullptr; m_pFileHandle = nullptr; } bool XmlFile::ReadFile(const char *FilePathName) { if (!strcmp(FilePathName, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } if (!(m_pFileHandle = fopen(FilePathName, "r"))) { m_LastErrCode = 2; m_LastErrMes = ERR_MES_2; return false; } struct stat FileStat; stat(FilePathName, &FileStat); m_FileSize = FileStat.st_size; m_pFileBuffur = new char[m_FileSize]; memset(m_pFileBuffur, 0, m_FileSize); fread(m_pFileBuffur, 1, m_FileSize, m_pFileHandle); fclose(m_pFileHandle); return true; } bool XmlFile::WriteFile(const char *FilePathName) { if (!strcmp(FilePathName, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } char FilePathNameBat[256] = { 0 }; strcpy(FilePathNameBat, FilePathName); strcat(FilePathNameBat, ".bak"); FILE *FileXmlTemp = fopen(FilePathName, "r"); FILE *FileBatTemp = fopen(FilePathNameBat, "w"); if (!FileXmlTemp || !FileBatTemp) { m_LastErrCode = 2; m_LastErrMes = ERR_MES_2; return false; } char FileStr[256] = { 0 }; while (fgets(FileStr, 256, FileXmlTemp)) { fprintf(FileBatTemp, "%s", FileStr); } fclose(FileXmlTemp); fclose(FileBatTemp); if (!(m_pFileHandle = fopen(FilePathName, "w"))) { m_LastErrCode = 2; m_LastErrMes = ERR_MES_2; return false; } delete[]m_pFileBuffur; m_pFileBuffur = new char[m_FileSize + 1024]; memset(m_pFileBuffur, 0, m_FileSize + 1024); NodeToBuffer(m_pRootNode, m_pFileBuffur, 0); fwrite(m_pFileBuffur, 1, strlen(m_pFileBuffur), m_pFileHandle); fclose(m_pFileHandle); return true; } bool XmlFile::AnalysisFile() { int i = 0; for (i; i < m_FileSize; i++) { if ('n' == m_pFileBuffur[i] || 't' == m_pFileBuffur[i]) { m_pFileBuffur[i] = ' '; } } if ('<' == m_pFileBuffur[0] && '?' == m_pFileBuffur[1]) { for (i = 0; i < m_FileSize; i++) { if ('>' == m_pFileBuffur[i]) { break; } } } XmlNode *pNode = new XmlNode; AnalysisXml(pNode, m_pFileBuffur + i + 1, strlen(m_pFileBuffur + i + 1)); m_pRootNode = pNode->m_pChild; m_pCurNode = m_pRootNode; return true; } void XmlFile::LocateRoot() { m_pCurNode = m_pRootNode; } bool XmlFile::LocateNode(XmlNode *pNode) { if (!pNode) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } m_pCurNode = pNode; return true; } bool XmlFile::LocateParent() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } m_pCurNode = m_pCurNode->m_pParent; return true; } bool XmlFile::LocatePrev() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } m_pCurNode = m_pCurNode->m_pPrev; return true; } bool XmlFile::LocateNext() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } m_pCurNode = m_pCurNode->m_pNext; return true; } bool XmlFile::LocatepChild() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } m_pCurNode = m_pCurNode->m_pChild; return true; } XmlNode *XmlFile::GetCurNode() { return m_pCurNode; } std::string XmlFile::GetCurNodeName() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return ""; } return m_pCurNode->m_Name; } std::string XmlFile::GetCurNodevalue() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return ""; } return m_pCurNode->m_Value; } XmlAttribute *XmlFile::GetCurNodeAttribute() { if (!m_pCurNode) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return nullptr; } return m_pCurNode->m_pAttribute; } XmlNode *XmlFile::AddXmlNode(XmlNode *pParent, std::string Name, std::string Value) { if (!pParent || "" == Name) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return nullptr; } XmlNode *pXmlNodeTemp = new XmlNode; pXmlNodeTemp->m_Name = Name; pXmlNodeTemp->m_Value = Value; pXmlNodeTemp->m_pParent = pParent; if (!pParent->m_pChild) { pParent->m_pChild = pXmlNodeTemp; } else { XmlNode *pPrev = pParent->m_pChild; while (pPrev->m_pNext) { pPrev = pPrev->m_pNext; } pPrev->m_pNext = pXmlNodeTemp; pXmlNodeTemp->m_pPrev = pPrev; } return pXmlNodeTemp; } bool XmlFile::UpdateXmlNode(XmlNode *pNode, std::string Name, std::string Value) { if (!pNode || "" == Name) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } pNode->m_Name = Name; pNode->m_Value = Value; return true; } void XmlFile::DeleteXmlNode(XmlNode *pNode) { DeleteNode(pNode); } bool XmlFile::AddNodeAttribute(XmlNode *pNode, std::string Name, std::string Value) { if (!pNode || "" == Name || "" == Value) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } XmlAttribute *pTemp = new XmlAttribute; pTemp->m_Name = Name; pTemp->m_Value = Value; if (!pNode->m_pAttribute) { pNode->m_pAttribute = pTemp; } else { XmlAttribute *pPrev = pNode->m_pAttribute; while (pPrev->m_pNext) { pPrev = pPrev->m_pNext; } pPrev->m_pNext = pTemp; } return true; } bool XmlFile::UpdateNodeAttribute(XmlNode *pNode, std::string Name, std::string Value) { XmlAttribute *pTemp = nullptr; pTemp = pNode->m_pAttribute; while (pTemp) { if (Name == pTemp->m_Name) { pTemp->m_Value = Value; return true; } } m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } void XmlFile::DeleteNodeAttribute(XmlNode *pNode) { DeleteAttribute(pNode->m_pAttribute); } void XmlFile::DeleteNodeAttribute(XmlNode *pNode, std::string Name) { XmlAttribute *pPrev = pNode->m_pAttribute; XmlAttribute *pTemp = nullptr; if (pPrev&&Name == pPrev->m_Name) { pNode->m_pAttribute = pNode->m_pAttribute->m_pNext; delete pPrev; return; } pTemp = pPrev->m_pNext; while (pTemp) { if (Name == pTemp->m_Name) { pPrev->m_pNext = pTemp->m_pNext; delete pTemp; return; } pPrev = pPrev->m_pNext; pTemp = pTemp->m_pNext; } } void AnalysisXml(XmlNode *pParent, char *Buffer, long BufferSize) { if (!pParent) { return; } int i = 0; int flag = 1; char *NodeBuffer = new char[1024]; memset(NodeBuffer, 0, 1024); char BeginName[32] = { 0 }; char EndName[32] = { 0 }; char *NextBuf = nullptr; XmlNode *pNodeTemp = nullptr; for (i; i < BufferSize; i++) { while (Buffer[i]) { if ('<' == Buffer[i] && '/' != Buffer[i + 1] && '!' != Buffer[i + 1]) { int j = 0; while ('>' != Buffer[i]) { NodeBuffer[j] = Buffer[i + 1]; j++; i++; } NextBuf = &Buffer[i + 1]; strncpy(BeginName, NodeBuffer, 32); for (int i = 0; i < strlen(BeginName); i++) { if (' ' == BeginName[i] || '=' == BeginName[i] || '>' == BeginName[i]) { BeginName[i] = 0; } } break; } i++; } while (Buffer[i]) { if ('<' == Buffer[i] && '/' == Buffer[i + 1]) { int j = 0; i += 2; while ('>' != Buffer[i]) { EndName[j] = Buffer[i]; j++; i++; } EndName[j] = 0; if (!strcmp(BeginName, EndName)) { pNodeTemp = new XmlNode; pNodeTemp->m_Name = std::string(BeginName); pNodeTemp->m_pParent = pParent; if (!pParent->m_pChild) { pParent->m_pChild = pNodeTemp; } else { XmlNode *pPrev = pParent->m_pChild; while (pPrev->m_pNext) { pPrev = pPrev->m_pNext; } pPrev->m_pNext = pNodeTemp; pNodeTemp->m_pPrev = pPrev; } char *pChr = strchr(NextBuf, '<'); if (pChr != NextBuf) { char Value[256] = { 0 }; strcpy(Value, std::string(NextBuf, pChr).data()); Trim(Value); pNodeTemp->m_Value = Value; } CreateNode(pNodeTemp, NodeBuffer); if (0 == flag) { AnalysisXml(pNodeTemp, NextBuf, strlen(NextBuf)); } else if (1 == flag) { AnalysisXml(pParent, NextBuf, strlen(NextBuf)); } delete[]NodeBuffer; return; } else { flag = 0; } } i++; } } } void CreateNode(XmlNode *pNode, char *pValue) { XmlAttribute *pAttributeTemp = nullptr; XmlAttribute *pPrev = nullptr; char Namevalue[32] = { 0 }; char *pChr = nullptr; pChr = strchr(pValue, ' '); if (!pChr) { return; } pValue = pChr + 1; int Len = strlen(pChr); while (true) { if (!(pChr = strchr(pValue, '='))) { return; } pAttributeTemp = new XmlAttribute; if (!pNode->m_pAttribute) { pNode->m_pAttribute = pAttributeTemp; } else { pPrev = pNode->m_pAttribute; while (pPrev->m_pNext) { pPrev = pPrev->m_pNext; } pPrev->m_pNext = pAttributeTemp; } strcpy(Namevalue, std::string(pValue, pChr).data()); Trim(Namevalue); pAttributeTemp->m_Name = Namevalue; pValue = pChr + 1; if (!(pChr = strchr(pValue, '"'))) { return; } pValue = pChr + 1; if (!(pChr = strchr(pValue, '"'))) { return; } strcpy(Namevalue, std::string(pValue, pChr).data()); Trim(Namevalue); pAttributeTemp->m_Value = Namevalue; pValue = pChr + 1; } } void Trim(char*Buffer) { int i = 0; int len = strlen(Buffer); for (i = len - 1; i >= 0; i--) { if (' ' != Buffer[i] && 't' != Buffer[i] && '"' != Buffer[i] && '"' != Buffer[i] && 'n' != Buffer[i]) { break; } Buffer[i] = 0; } for (i = 0; i < len; i++) { if (' ' != Buffer[i] && 't' != Buffer[i] && '"' != Buffer[i] && '"' != Buffer[i] && 'n' != Buffer[i]) { break; } } if (0 != i) { strncpy(Buffer, Buffer + i, len - i); Buffer[len - i] = 0; } } void NodeToBuffer(XmlNode *pNode, char *pBuffer, int Depth) { if (!pNode) { return; } for (int i = 0; i < Depth; i++) { strcat(pBuffer, "t"); } strcat(pBuffer, "<"); strcat(pBuffer, pNode->m_Name.data()); XmlAttribute *pAtt = pNode->m_pAttribute; while (pAtt) { strcat(pBuffer, " "); strcat(pBuffer, pAtt->m_Name.data()); strcat(pBuffer, "=""); strcat(pBuffer, pAtt->m_Value.data()); strcat(pBuffer, """); pAtt = pAtt->m_pNext; } strcat(pBuffer, ">"); strcat(pBuffer, pNode->m_Value.data()); if (pNode->m_pChild) { strcat(pBuffer, "n"); NodeToBuffer(pNode->m_pChild, pBuffer, Depth + 1); for (int i = 0; i < Depth; i++) { strcat(pBuffer, "t"); } strcat(pBuffer, ""); strcat(pBuffer, pNode->m_Name.data()); strcat(pBuffer, ">n"); } else if (pNode->m_pNext) { strcat(pBuffer, ""); strcat(pBuffer, pNode->m_Name.data()); strcat(pBuffer, ">n"); NodeToBuffer(pNode->m_pNext, pBuffer, Depth); } else { strcat(pBuffer, ""); strcat(pBuffer, pNode->m_Name.data()); strcat(pBuffer, ">n"); } return; } void DeleteNode(XmlNode *pNode) { if (!pNode) { return; } DeleteNode(pNode->m_pChild); DeleteNode(pNode->m_pNext); DeleteAttribute(pNode->m_pAttribute); pNode->m_pParent = nullptr; pNode->m_pPrev = nullptr; pNode->m_pNext = nullptr; pNode->m_pChild = nullptr; pNode->m_pAttribute = nullptr; delete pNode; } void DeleteAttribute(XmlAttribute *pAttribute) { if (!pAttribute) { return; } DeleteAttribute(pAttribute->m_pNext); delete pAttribute; pAttribute = nullptr; }
文章以及源码均为原创,当然欢迎转载,转载请加说明



