TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。
在自己项目中使用TinyXML需要把六个cpp文件加入工程中,而且每个cpp文件需要包含stdafx.h头文件,否则报错,在文件中包含 tinyxml.h 头文件即可使用TinyXML,如下截图所示:
代码实现,例如我通过代码遍历下面的xml文件
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Config>
<Stock>
<key stockScore="0" increaseProbability="0"/>
<key stockScore="100000" increaseProbability="1.5"/>
<key stockScore="300000" increaseProbability="2.0"/>
</Stock>
<pond>
<money pondScore="0" increaseProbability="5"/>
<money pondScore="100000" increaseProbability="2.5"/>
<money pondScore="300000" increaseProbability="3.0"/>
</pond>
</Config>
代码实现
TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement(); //获取根节点Config
TiXmlElement *pEle=RootElement;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
StuElement != NULL;
StuElement = StuElement->NextSiblingElement())//下一个子节点
{
if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
{
for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
{
TiXmlAttribute *pAttr=stock->FirstAttribute();//得到节点的第一个属性
while( NULL != pAttr) //输出所有属性
{
CString cs;
cs.Format("lwlog::Name()=%s Value=%s",pAttr->Name(),pAttr->Value());
OutputDebugString(cs);
pAttr=pAttr->Next();
}
}
}
if(0==strcmp(StuElement->Value(),"pond"))
{
for(TiXmlElement *pond = StuElement->FirstChildElement();pond != NULL;pond = pond->NextSiblingElement())
{
TiXmlAttribute *pAttr=pond->FirstAttribute();
while( NULL != pAttr)
{
CString cs;
cs.Format("lwlog::Name()=%s Value=%s",pAttr->Name(),pAttr->Value());
OutputDebugString(cs);
pAttr=pAttr->Next();
}
}
}
}
打印结果
假如我有以下xml文档,我想读取节点key0,key1,key2属性stockScore的值到程序变量中,实现代码如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Config>
<Stock>
<key0 stockScore="0" increaseProbability="0"/>
<key1 stockScore="100000" increaseProbability="1.5"/>
<key2 stockScore="300000" increaseProbability="2.0"/>
<key3>game</key3>
</Stock>
<pond>
<money pondScore="0" increaseProbability="5"/>
<money pondScore="100000" increaseProbability="2.5"/>
<money pondScore="300000" increaseProbability="3.0"/>
</pond>
</Config>
TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement(); //获取根节点Config
TiXmlElement *pEle=RootElement;
int score[3]={0,0,0};
int index=0;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
StuElement != NULL;
StuElement = StuElement->NextSiblingElement())//下一个子节点
{
if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
{
for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
{
stock->Attribute("stockScore",&score[index++]);//存储属性值
}
}
}
根据以上xml文档,我想读取节点key3的文本game,实现代码如下:
TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement(); //获取根节点Config
TiXmlElement *pEle=RootElement;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
StuElement != NULL;
StuElement = StuElement->NextSiblingElement())//下一个子节点
{
if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
{
for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
{
if(0==strcmp(stock->Value(),"key3"))
{
const char *p=stock->GetText();//p指向字符串game
CString cs;
cs.Format("lwlog::p=%s",p);
OutputDebugString(cs);
}
}
}
}
假如我想改写节点key2属性stockScore的值,实现代码如下:
TiXmlDocument mydoc;//xml文档对象
bool loadOk=mydoc.LoadFile("lkpy_config_33000306.xml",TIXML_ENCODING_UTF8);//根据UTF-8格式加载xml文档
if(!loadOk)
{
exit(1);
}
TiXmlElement *RootElement=mydoc.RootElement(); //获取根节点Config
TiXmlElement *pEle=RootElement;
//遍历该节点
for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一个子节点
StuElement != NULL;
StuElement = StuElement->NextSiblingElement())//下一个子节点
{
if(0==strcmp(StuElement->Value(),"Stock"))//开始遍历名字为"Stock"的节点的子节点
{
for(TiXmlElement *stock = StuElement->FirstChildElement();stock != NULL;stock = stock->NextSiblingElement())
{
if(0==strcmp(stock->Value(),"key2"))
{
int n=123456;
stock->SetAttribute("stockScore",n);//设置成我想要的值
}
}
}
}
mydoc.SaveFile();//记住一定要调用保存函数,否则修改无效
创建一个stu_info.xml文档
//创建xml文件
int writeXmlFile()
{
TiXmlDocument *writeDoc = new TiXmlDocument; //xml文档指针
//文档格式声明
TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "UTF-8", "yes");
writeDoc->LinkEndChild(decl); //写入文档
int n = 3; //父节点个数
TiXmlElement *RootElement = new TiXmlElement("Info");//根元素
RootElement->SetAttribute("num", n); //属性
writeDoc->LinkEndChild(RootElement);
for(int i=0; i<n; i++)//n个父节点
{
TiXmlElement *StuElement = new TiXmlElement("Stu");//Stu
//设置属性
StuElement->SetAttribute("class","A");
if(2 == i)
{
StuElement->SetAttribute("class","B");
}
StuElement->SetAttribute("id",i+1);
StuElement->SetAttribute("flag", (i+1)*10);
RootElement->LinkEndChild(StuElement);//父节点写入文档
//姓名
TiXmlElement *nameElement = new TiXmlElement("name");
StuElement->LinkEndChild(nameElement);
TiXmlText *nameContent = new TiXmlText("mike");
nameElement->LinkEndChild(nameContent);
//分数
TiXmlElement *scoreElement = new TiXmlElement("score");
StuElement->LinkEndChild(scoreElement);
TiXmlText *scoreContent = new TiXmlText("88");
scoreElement->LinkEndChild(scoreContent);
//城市
TiXmlElement *cityElement = new TiXmlElement("city");
StuElement->LinkEndChild(cityElement);
TiXmlText *cityContent = new TiXmlText("Shenzhen");
cityElement->LinkEndChild(cityContent);
}
writeDoc->SaveFile("stu_info.xml");
delete writeDoc;
return 1;
}
生成的xml文件内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Info num="3">
<Stu class="A" id="1" flag="10">
<name>mike</name>
<score>88</score>
<city>Shenzhen</city>
</Stu>
<Stu class="A" id="2" flag="20">
<name>mike</name>
<score>88</score>
<city>Shenzhen</city>
</Stu>
<Stu class="B" id="3" flag="30">
<name>mike</name>
<score>88</score>
<city>Shenzhen</city>
</Stu>
</Info>