IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++实现xml文件的读写解析等操作源码 -> 正文阅读

[C++知识库]C/C++实现xml文件的读写解析等操作源码

C/C++读写解析xml文件,写的比较简单,读写解析测试了下,定位更新等操作懒得测试了,估计有很多可以优化的,欢迎各位阅读,也欢迎来讨论

/****************************************
文件名称:xmlfile.h
作者:木马小Z
创建日期:20210910
版本:V1.0
****************************************/
#include <iostream>
#include <string.h>

#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();
/****************************************
函数名称:ReadFile
参数列表:FilePathName 文件目录
用途    :读取ini文件
返回值  :成功true 失败false
****************************************/
	bool ReadFile(const char *FilePathName);
/****************************************
函数名称:WriteFile
参数列表:FilePathName 文件目录
用途    :写入ini文件
返回值  :成功true 失败false
****************************************/
	bool WriteFile(const char *FilePathName);
/****************************************
函数名称:AnalysisFile
参数列表:
用途    :解析ini文件
返回值  :成功true 失败false
****************************************/
	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);

/****************************************
文件名称:xmlfile.cpp
作者:木马小Z
创建日期:20210910
版本:V1.0
****************************************/
#include "xmlfile.h"
#include <sys/stat.h>

XmlAttribute::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;
}

文章以及源码均为原创,当然欢迎转载,转载请加说明

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-07 13:40:26  更:2021-10-07 13:42:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 2:41:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码