转自:http://blog.163.com/kin_jiezi/blog/static/3683682201172593616285/
读取和设置xml配置文件是最常用的操作,试用了几个C++的XML解析器,个人感觉TinyXML是使用起来最舒服的,因为它的API接口和Java的十分类似,面向对象性很好。
TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。
DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。
如下是一个XML片段:Person ID ="1" name >周星星 </ age >20 Person ="2" >白晶晶 >18 >
在TinyXML中,根据XML的各种元素来定义了一些类:
TiXmlBase:整个TinyXML模型的基类。
TiXmlAttribute:对应于XML中的元素的属性。
TiXmlNode:对应于DOM结构中的节点。
TiXmlComment:对应于XML中的注释
TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0"?>。
TiXmlDocument:对应于XML的整个文档。
TiXmlElement:对应于XML的元素。
TiXmlText:对应于XML的文字部分
TiXmlUnknown:对应于XML的未知部分。
TiXmlHandler:定义了针对XML的一些操作。
TinyXML是个解析库,主要由DOM模型类(TiXmlBase、TiXmlNode、TiXmlAttribute、TiXmlComment、TiXmlDeclaration、TiXmlElement、TiXmlText、TiXmlUnknown)和操作类(TiXmlHandler)构成。它由两个头文件(.h文件)和四个CPP文件(.cpp文件)构成,用的时候,只要将(tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp)导入工程就可以用它的东西了。如果需要,可以将它做成自己的DLL来调用。举个例子就可以说明一切。。。
对应的XML文件:#include " tinyxml.h "
#include tinystr.h "
#include< string>
#include<windows.h>
#include<atlstr.h>
using namespacestd;
CStringGetAppPath()
{//获取应用程序根目录
TCHARmodulePath[MAX_PATH];
GetModuleFileName(NULL,modulePath,MAX_PATH);
CStringstrModulePath(modulePath);
strModulePath=strModulePath.Left(strModulePath.ReverseFind(_T('\\')));
returnstrModulePath;
}
boolCreateXmlFile( string&szFileName)
{创建xml文件,szFilePath为文件保存的路径,若创建成功返回true,否则false
try
{
创建一个XML的文档对象。
TiXmlDocument*myDocument=newTiXmlDocument();
创建一个根元素并连接。
TiXmlElement*RootElement=newTiXmlElement("Persons");
myDocument->LinkEndChild(RootElement);
创建一个Person元素并连接。
TiXmlElement*PersonElement=Person");
RootElement->LinkEndChild(PersonElement);
设置Person元素的属性。
PersonElement->SetAttribute(ID",1");
创建name元素、age元素并连接。
TiXmlElement*NameElement=name");
TiXmlElement*AgeElement=age");
PersonElement->LinkEndChild(NameElement);
PersonElement->LinkEndChild(AgeElement);
设置name元素和age元素的内容并连接。
TiXmlText*NameContent=newTiXmlText(周星星");
TiXmlText*AgeContent=22");
NameElement->LinkEndChild(NameContent);
AgeElement->LinkEndChild(AgeContent);
CStringappPath=GetAppPath();
stringseperator=";
stringfullPath=appPath.GetBuffer(0)+seperator+szFileName;
myDocument->SaveFile(fullPath.c_str());保存到文件
}
catch(string&e)
{
returnfalse;
}
true;
}
boolReadXmlFile( string&szFileName)
{读取Xml文件,并遍历try
{
CStringappPath=GetAppPath();
0)+seperator+szFileName;
newTiXmlDocument(fullPath.c_str());
myDocument->LoadFile();
获得根元素,即Persons。
TiXmlElement*RootElement=myDocument->RootElement();
输出根元素名称,即输出Persons。
cout<<RootElement->Value()<<endl;
获得第一个Person节点。
TiXmlElement*FirstPerson=RootElement->FirstChildElement();
获得第一个Person的name节点和age节点和ID属性。
TiXmlElement*NameElement=FirstPerson->FirstChildElement();
TiXmlElement*AgeElement=NameElement->NextSiblingElement();
TiXmlAttribute*IDAttribute=FirstPerson->FirstAttribute();
输出第一个Person的name内容,即周星星;age内容,即;ID属性,即。
cout<<NameElement->FirstChild()->Value()<<endl;
cout<<AgeElement->FirstChild()->Value()<<endl;
cout<<IDAttribute->Value()<<endl;
}
string&e)
{
true;
}
intmain()
{
stringfileName=info.xml";
CreateXmlFile(fileName);
ReadXmlFile(fileName);
}
1.首先下载TinyXML库的文件,这里给出链接,大家自己去下吧
http://prdownloads.sourceforge.net/tinyxml
2.在TinyXML的目录里面找到tinystr.h,tinyxml.h,tinystr.cpp,tinyxml.cpp,tinyxmlerror.cpp,tinyxmlparser.cpp六个文件加入到刚刚创建的项目中去
3.在相应的工程文件中加入两个头文件
#include "tinyxml.h"
#include "tinystr.h"
4.tinystr.cpp,tinyxmlparser.cpp六个文件的第一行加入头文件
#include "stdafx.h"
至于为什么,在vc的win32工程cpp文件中,如果不加该文件头的话会提示文件没有结束标志
在TinyXML中,根据XML的各种元素来定义了一些类:
TiXmlBase:整个TinyXML模型的基类。
TiXmlAttribute:对应于XML中的元素的属性。
TiXmlNode:对应于DOM结构中的节点。
TiXmlComment:对应于XML中的注释。
TiXmlDeclaration:对应于XML中的申明部分,即<?versiong="1.0" ?>。
TiXmlDocument:对应于XML的整个文档。
TiXmlElement:对应于XML的元素。
TiXmlText:对应于XML的文字部分。
TiXmlUnknown:对应于XML的未知部分。
TiXmlHandler:定义了针对XML的一些操作。
例如:
<!–Ourtodolistdata–>
<ToDo>
<Itempriority="1">Gotothe<bold>Toystore!</bold></Item>
<Itempriority="2">Dobills</Item>
</ToDo>
整个对象树:
TiXmlDocument "demo.xml"
TiXmlDeclaration "version=’1.0′" "standalone=no"
TiXmlComment " Our to do list data"
TiXmlElement "ToDo"
TiXmlElement "Item" Attribtutes: priority = 1
TiXmlText "Go to the "
TiXmlElement "bold"
TiXmlText "Toy store!"
TiXmlElement "Item" Attributes: priority=2
TiXmlText "Do bills"
在tinyXML中,用FirstChild("名字")查找节点时,调用FirstChild函数的节点与要查找的节点必须成“父子关系”。
句柄
想要健壮地读取一个XML文档,检查方法调用后的返回值是否为null是很重要的。一种安全的检错实现可能会产生像这样的代码:
if (root)
{
TiXmlElement*element=root->FirstChildElement("Element);
if(element)
childChild(child)
child2NextSiblingElement((child2)
{
Finallydosomethinguseful.
用句柄的话就不会这么冗长了,使用TiXmlHandle类,前面的代码就会变成这样:
TiXmlElement child2 docHandle.FirstChild( ).FirstChild( Element ).Child( Child , 1 ).ToElement();
(child2)
dosomethinguseful
一、读取XML,设置节点文本
如下XML片段:
< ZXML > ZAPP VBS_RUNTIME_PARAMS BROADCAST_VERSION info ="版本" 8 </ BROADCAST_VERSION Broadcast FileCount ="资源文件个数" 69 FileCount SOURCE_1 ID ="图片编号" ID Version ="图片版本" Version Path ="图片路径" /mnt/share/1.bmp Path FileMode ="文件处理模式" 0 FileMode SOURCE_2 /mnt/share/2.bmp 2
.
>
要设置BROADCAST_VERSION节点的值 8为其他值,可参考如下代码(将值加1):
用ReplaceChild( TiXmlNode* replaceThis,const TiXmlNode& withThis )方法替换
TiXmlDocumentdoc("zapp.conf");
doc.LoadFile();
TiXmlHandledocHandle( doc);
TiXmlElement Broadcast_ver ).FirstChildElement( ).ToElement();
TiXmlNode oldnode -> FirstChild();
const char ver GetText();
int oldVer atoi(ver);
CStringnewVer;
newVer.Format( %d + );
TiXmlTextnewText(newVer);
Broadcast_ver ReplaceChild(oldnode,newText);
AfxMessageBox(Broadcast_ver GetText()); // 输出值 doc.SaveFile();
二,删除节点,属性值
RemoveChild( TiXmlNode* removeThis )方法删除父节点的子节点,
RemoveAttribute( const char * name )方法删除属性值.
例如删除BROADCAST_VERSION节点
).ToElement();
TiXmlNode node FirstChild( );
Broadcast_ver RemoveChild(node);