VC++下使用tinyXML解析XML全程解析
第一:首先是下载tinyXML库(网上一堆不多说)
第二:关于如何配置的问题。
1.把解压后的tinyXML库文件放在固定的位置。
2.创建新项目,然后把tinyXML中的 tinystr.h, tinyxml.h, tinystr.cpp, tinyxml.cpp, tinyxmlerror.cpp, tinyxmlparser.cpp 六个文件加入到刚刚创建的项目所在的文件夹中去,然后在添加到工程。
3.然后就是在你创建的文件开头添加如下头文件:
#include "tinyxml.h" #include "tinystr.h" 4.如果你是用VS创建的工程,就在tinystr.h, tinyxml.h, tinystr.cpp, tinyxml.cpp, tinyxmlerror.cpp, tinyxmlparser.cpp 这六个文件开头第一行加上#include “stdafx.h” 至于为什么,在vc的win32工程cpp文件中,如果不加该文件头的话会提示文件没有结束标志 以上就是初期的工程配置步骤,下面就是要开始编写代码了。 第三:TinyXML基础 下面是一些基本的元素与xml的对应关系:举个例子,来看看其相互之间是如何对应的。
假设我们有如下的一个XML文件:
<?xml version="1.0" ?> <!-- This is comment here. --> <Data> <Player level="12">Kasi</Player> <Player>Gosla</Player> </Data>
它与TinyXml元素的对应关系,如下:
TiXmlDocument "demo.xml"
TiXmlDeclaration "version='1.0'"
TiXmlComment "This is comment here."
TiXmlElement "Data"
TiXmlElement "Player" Attribtutes: level=12
TiXmlText "Kasi"
TiXmlElement "Player"
TiXmlText "Gosla"
下面来大体解说一下转换的缘由,一些概念若不大明白,不必着急,一直往下看,便可明了。
<?xml version="1.0" ?>是一个声明,将其转化为TiXmlDeclaration,它是TiXmlDocument的第一个child。它是一个指令或者说是特殊的标签,所以在使用的时候,常把它转化为TiXmlUnknown(处理的时候照着原样写出来),这样它的信息就不会丢失。
<!-- This is comment here. -->
文档的注释,转化为TiXmlComment
<Data>
这个标签对应于一个TiXmlElement,其没有具体的属性(attribute),而是含有另外两个child(<Player>)。
<Player level="12">
这个就是<Data>的child,也是一个TiXmlElement元素,它具有一个属性(属性名为level, 值为12)
Kasi
这是<Player level="12">的child,为一个TiXmlText。其为叶节点(leaf node),即不再含有其他的child。
四、TinyXML应用例子
下面的例子,我们将使用TinyXML,从程序中生成上面的XML文件。从例子中,可以看到如何打开、保存文件。
#include <stdlib.h> #include <stdio.h> #include "tinyxml.h" const char* demoStart = "<?xml version=\"1.0\"?>\n" "<!--This is comment here.-->\n" "<Data>\n" "<Player level=\"12\">Kasi</Player>\n" "<Player>Gosla</Player>\n" "</Data>\n"; int _tmain(int argc, _TCHAR* argv[]) { TiXmlDocument OutputDoc("demotest.xml"); OutputDoc.Parse(demoStart); if(OutputDoc.Error()) { printf("Error in %s:%s\n",OutputDoc.Value(),OutputDoc.ErrorDesc()); exit(1); } OutputDoc.SaveFile(); TiXmlDocument InputDoc("demotest.xml"); bool loadOkay = InputDoc.LoadFile(); if(!loadOkay) { printf("Could not load 'demotest.xml':Error='%s'.\n",InputDoc.ErrorDesc()); exit(1); } return 0; }
其中打开一个文件还可以写成下面的形式:
TiXmlDocument InputDoc; bool loadOkay = InputDoc.LoadFile("demotest.xml");
两种写法看自己的喜好,都一样。
下面,我们来看看,如何从XML文件中将数据读出。
为完整演示TinyXML的功能,我们需要一个更复杂一些的XML文件,如下(demo.xml):
<?xml version="1.0" ?> <Data> <!-- This is comment here. --> <Player level="12" rate="0.2" desc='Great guy!'>Kasi</Player> <Player> <Name>Gosla</Name> <Level>13</Level> <Rate>0.3</Rate> <Desc>Wonderful guy!</Desc> </Player> </Data>
完整的实例代码如下:
#include "stdafx.h" #include <iostream> #include <stdio.h> #include <stdlib.h> #include <string> #include "tinyxml.h" #include "tinystr.h" using namespace std; int main() { TiXmlDocument doc; bool loadOkay =doc.LoadFile("config.xml"); if(!loadOkay) { printf("Could not load 'demo.xml'.Error='%s'.\n",doc.ErrorDesc()); exit(1); } TiXmlNode * node = 0 ; TiXmlElement * dataElement = 0; TiXmlElement * itemElement = 0; TiXmlComment * itemComment = 0; TiXmlText * itemText = 0; int level = 0; double rate = 0; std::string name,desc; node = doc.FirstChild("Data"); dataElement = node->ToElement(); node = dataElement->FirstChild(); itemComment = node->ToComment(); printf("comment :%s\n",itemComment->Value()); node = dataElement ->FirstChildElement(); itemElement = node ->ToElement(); itemText = itemElement->FirstChild()->ToText(); itemElement->QueryIntAttribute("level",&level); itemElement->QueryDoubleAttribute("rate",&rate); desc = itemElement->Attribute("desc"); name = itemText->Value(); printf("name:%s,level:%d,rate:%f,desc:%s\n",name.c_str(),level,rate,desc.c_str()); itemElement = itemElement->NextSiblingElement(); itemElement = itemElement->FirstChildElement(); itemText = itemElement->FirstChild()->ToText(); name = itemText->Value(); itemText = itemElement->FirstChild()->ToText(); level = atoi(itemText->Value()); itemElement = itemElement->NextSiblingElement(); itemText = itemElement->FirstChild()->ToText(); rate =atof(itemText->Value()); itemElement = itemElement->NextSiblingElement(); itemText = itemElement->FirstChild()->ToText(); desc = itemText->Value(); printf("name:%s,level:%d,rate;%f,desc:%s\n",name.c_str(),level,rate,desc.c_str()); return 0; }
运行结果完美。有了例子就可以慢慢学习tinyXML了。。。。持续更新中。。。
更新建议:
用过tinyXml这么久之后,现在我发现其实效率最高速度最快的还是rapidXml解析库,对于需要频繁读取Xml文件的程序,这个库平均比tinyXml要快30倍左右,大家可以去看看rapidXml库解析xml文件,比tinyxml简单多了,而且逻辑清晰易懂,容易上手。