最近有使用到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部分内容:
张一一
15
男
180
75
王二
12
女
160
50
1、添加解析类XmlParser。
关键成员:
public:
void ReadXml(CString strXmlPath, vector& arrStu);
void WriteXml(CString strXmlPath);
void AppendXml(Student ss, CString strXmlPath);//尾部追加
void SetArrayInfo(vector arr);
void ModifyXml(CString strXmlPath);
private:
vector 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& 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文本这种树形结构,只需要析构掉根节点就可以。