TinyXml解析XML文本

最近有使用到TinyXml库解析文件,网上优秀实例很多,但还是想把自己思路写一写。刚毕业C++小菜鸟,有望斧正一二,不胜感激。

TinyXML是一个开源的解析XML的C++解析库,跨Windows/Linux平台,用起来很方便。

下载地址:https://sourceforge.net/projects/tinyxml/

使用说明:
demo环境:Win7 + VS2013
使用TinyXML需要把库包含的6个文件拷贝到项目中,这六个文件是:tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp;
可以在工程里面新建筛选器XML,把六个文件加载到该筛选器下。
提示包含头文件stdafx.h问题,可以在文件属性里去掉四个库cpp预编译头。

截取XML部分内容:

<class>
    <student>
        <name>张一一</name>
        <age>15</age>
        <sex>男</sex>
        <height>180</height>
        <weight>75</weight>
    </student>
    <student>
        <name>王二</name>
        <age>12</age>
        <sex>女</sex>
        <height>160</height>
        <weight>50</weight>
    </student>
</class>

1、添加解析类XmlParser。

关键成员:

public:
	void ReadXml(CString strXmlPath, vector<Student>& arrStu);
	void WriteXml(CString strXmlPath);
	void AppendXml(Student ss, CString strXmlPath);//尾部追加
	void SetArrayInfo(vector<Student> arr);
	void ModifyXml(CString strXmlPath);
private:
	vector<Student> m_arrStu;

2、定义数据结构。

struct Student
{
	string name;
	int age;
	string sex;
	int height;
	int weight;
};

3、相关成员的实现。

3.1 写操作:

void XmlParser::WriteXml(CString strXmlPath)
{
	if (m_arrStu.empty())
		return;
	CString fileName = "test.xml";
	TiXmlDocument *pDoc = new TiXmlDocument();				//创建xml文档对象

	TiXmlDeclaration *pDeclare = new TiXmlDeclaration("1.0", "gb2312", "");
	pDoc->LinkEndChild(pDeclare);

	TiXmlElement *pRoot = new TiXmlElement("class");  	//创建一个根结点
	pDoc->LinkEndChild(pRoot);								//链接到文档对象下


	for (int i = 0; i < m_arrStu.size();i++)
	{
		CString str;
		TiXmlElement *pFml = new TiXmlElement("student");		//创建一个节点
		pRoot->LinkEndChild(pFml);							//链接到节点

		TiXmlElement *pName = new TiXmlElement("name");
		pFml->LinkEndChild(pName);
		str = m_arrStu[i].name.c_str();
		TiXmlText *pNameText = new TiXmlText(str);
		pName->LinkEndChild(pNameText);

		TiXmlElement *pAge = new TiXmlElement("age");
		pFml->LinkEndChild(pAge);
		str.Format("%d",m_arrStu[i].age);
		TiXmlText *pAgeText = new TiXmlText(str);
		pAge->LinkEndChild(pAgeText);

		TiXmlElement *pSex = new TiXmlElement("sex");
		pFml->LinkEndChild(pSex);
		str = m_arrStu[i].sex.c_str();
		TiXmlText *pSexText = new TiXmlText(str);
		pSex->LinkEndChild(pSexText);

		TiXmlElement *pHeight = new TiXmlElement("height");
		pFml->LinkEndChild(pHeight);
		str.Format("%d", m_arrStu[i].height);
		TiXmlText *pHeightText = new TiXmlText(str);
		pHeight->LinkEndChild(pHeightText);


		TiXmlElement *pWeight = new TiXmlElement("weight");
		pFml->LinkEndChild(pWeight);
		str.Format("%d", m_arrStu[i].weight);
		TiXmlText *pWeightText = new TiXmlText(str);
		pWeight->LinkEndChild(pWeightText);
	}

	pDoc->SaveFile(strXmlPath);		//保存到文件

	if (pDoc)
	{
		delete pDoc;
		pDoc = NULL;
	}
}

3.1 读操作:

void XmlParser::ReadXml(CString strXmlPath, vector<Student>& arrStu)
{
	//读取xml文件中的参数值
	TiXmlDocument* pDoc = new TiXmlDocument();
	if (!pDoc->LoadFile(strXmlPath))
	{
		return;
	}
	TiXmlElement* pRoot = pDoc->RootElement();		//根目录

	TiXmlElement* NextElement = pRoot->FirstChildElement();	//根目录下的第一个节点层
	while (NextElement != NULL)						//判断有没有读完
	{
		if (NextElement->ValueTStr() == "student")		//读到fml节点
		{
			CString str;
			Student ss{};
			//分别读取
			TiXmlElement* pName = NextElement->FirstChildElement();
			ss.name = pName->GetText();

			TiXmlElement* pAge = pName->NextSiblingElement();
			ss.age = atoi(pAge->GetText());

			TiXmlElement* pSex = pAge->NextSiblingElement();
			ss.sex = pSex->GetText();		

			TiXmlElement* pHeight = pSex->NextSiblingElement();
			ss.height = atoi(pHeight->GetText());

			TiXmlElement* pWeight = pHeight->NextSiblingElement();
			ss.weight = atoi(pWeight->GetText());

			arrStu.push_back(ss);
		}
		NextElement = NextElement->NextSiblingElement();
	}

	delete pDoc;
	pDoc = NULL;
}

3.3 修改。(注:修改对象分节点名称和节点文本内容)

void XmlParser::ModifyXml(CString strXmlPath)
{
	//读取xml文件中的参数值
	TiXmlDocument* pDoc = new TiXmlDocument();
	if (!pDoc->LoadFile(strXmlPath))
	{
		return;
	}
	TiXmlElement* pRoot = pDoc->RootElement();		//根目录

	TiXmlElement* NextElement = pRoot->FirstChildElement();	//根目录下的第一个节点层
	while (NextElement != NULL)						//判断有没有读完
	{
		if (NextElement->ValueTStr() == "student")		//读到fml节点
		{
			CString str;
			Student ss{};
			//分别读取
			TiXmlElement* pName = NextElement->FirstChildElement();
			ss.name = pName->GetText();
			//1、重新设置节点名为 NAME ,之前是name
			//pName->SetValue("NAME");
			//2、重新设置节点文本内容
			/*TiXmlNode *pText = pName->FirstChild();
			pText->SetValue("12");*/

			TiXmlElement* pAge = pName->NextSiblingElement();
			ss.age = atoi(pAge->GetText());

			TiXmlElement* pSex = pAge->NextSiblingElement();
			ss.sex = pSex->GetText();

			TiXmlElement* pHeight = pSex->NextSiblingElement();
			ss.height = atoi(pHeight->GetText());

			TiXmlElement* pWeight = pHeight->NextSiblingElement();
			ss.weight = atoi(pWeight->GetText());
		}
		NextElement = NextElement->NextSiblingElement();
	}

	pDoc->SaveFile(strXmlPath);
	delete pDoc;
	pDoc = NULL;
}

3.4 尾部追加:

void XmlParser::AppendXml(Student ss, CString strXmlPath)
{
	if (ss.name == "")
		return;

	TiXmlDocument* pDoc = new TiXmlDocument();
	if (!pDoc->LoadFile(strXmlPath))
	{
		return;
	}
	TiXmlElement* pRoot = pDoc->RootElement();//根目录

	CString str;
	TiXmlElement *pFml = new TiXmlElement("student");		//创建一个节点
	pRoot->LinkEndChild(pFml);							//链接到节点

	TiXmlElement *pName = new TiXmlElement("name");
	pFml->LinkEndChild(pName);
	str = ss.name.c_str();
	TiXmlText *pNameText = new TiXmlText(str);
	pName->LinkEndChild(pNameText);

	TiXmlElement *pAge = new TiXmlElement("age");
	pFml->LinkEndChild(pAge);
	str.Format("%d", ss.age);
	TiXmlText *pAgeText = new TiXmlText(str);
	pAge->LinkEndChild(pAgeText);

	TiXmlElement *pSex = new TiXmlElement("sex");
	pFml->LinkEndChild(pSex);
	str = ss.sex.c_str();
	TiXmlText *pSexText = new TiXmlText(str);
	pSex->LinkEndChild(pSexText);

	TiXmlElement *pHeight = new TiXmlElement("height");
	pFml->LinkEndChild(pHeight);
	str.Format("%d", ss.height);
	TiXmlText *pHeightText = new TiXmlText(str);
	pHeight->LinkEndChild(pHeightText);


	TiXmlElement *pWeight = new TiXmlElement("weight");
	pFml->LinkEndChild(pWeight);
	str.Format("%d", ss.weight);
	TiXmlText *pWeightText = new TiXmlText(str);
	pWeight->LinkEndChild(pWeightText);

	pDoc->SaveFile(strXmlPath);
	if (pDoc)
	{
		delete pDoc;
		pDoc = NULL;
	}
}

4、运行。
4.1 写:
在这里插入图片描述
4.2 读:
在这里插入图片描述
4.3 修改:
4.3.1 修改节点名:
在这里插入图片描述
4.3.2 修改节点文本内容:
在这里插入图片描述
修改指定节点也很方便,只需要遍历找到该节点对象,即可修改。关键方法: GetText()//获取节点文本,注意设置方法并不是SeTText(),而是SetValue().
4.4 尾部追加:
在这里插入图片描述
5、关于析构,对于XML文本这种树形结构,只需要析构掉根节点就可以。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值