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简单多了,而且逻辑清晰易懂,容易上手。

 

posted @ 2013-03-18 17:31  foundwant  阅读(960)  评论(0编辑  收藏  举报