体验TinyXML读写XML文件数据

来源:互联网 发布:sql rownum用法 编辑:程序博客网 时间:2024/04/28 18:36

 前一阵子做一个客服回复玩家问题工具,要用到读写XML文件的数据,同事推荐用TinyXML,于是,开始了我与TinyXML的亲密之旅。

先简单说说配置:首先下载TinyXML库的文件,然后在 TinyXML 的目录里面找到tinystr.h, tinyxml.h,tinystr.cpp,tinyxml.cpp, tinyxmlerror.cpp,tinyxmlparser.cpp六个文件加入到自己的项目中去,在相应的工程文件中加入两个头文件 #include "tinyxml.h" ,#include "tinystr.h",在 tinystr.cpp,tinyxml.cpp, tinyxmlerror.cpp, tinyxmlparser.cpp四个文件的第一行加入头文件 #include "stdafx.h",然后即可使用TinyXML编程。

要读取的xml 数据如下:

  1. xml version="1.0" encoding="gb2312" standalone="yes" ?> 
  2. <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
  3. <prop> 
  4. <id>100id> 
  5. <title>test 1title> 
  6. prop> 
  7. <prop> 
  8. <id>200id> 
  9. <title>test 2title> 
  10. prop> 
  11. root> 

注意要将 encoding设为gb2312格式,我一开始设置的是utf-8,结果遇到在程序里

写入中文没问题, 但在读出该中文时却有异常,把后面的

了,后来和一同事讨论后才知道是编码问题。

  1. string filefullPath = 要读取xml文件的绝对路径  
  2. //创建文件对象  
  3. TiXmlDocument * myDocument = new TiXmlDocument(filefullPath.c_str());  
  4. //加载文件数据  
  5. myDocument->LoadFile();  
  6. //获取根节点  
  7. TiXmlElement *RootElement = myDocument->RootElement(); 

以下是简单的读取操作:

  1. //第一个子节点  
  2. TiXmlElement *CurrentPerson = RootElement->FirstChildElement();  
  3. //遍历获取指定节点数据  
  4. while(CurrentPerson)  
  5. {  
  6. //子节点第一个属性 id  
  7. TiXmlElement *IdElement = CurrentPerson->FirstChildElement();  
  8. //第一个属性的值  
  9. int nodeID = atoi(IdElement->FirstChild()->Value());  
  10. //子节点第二个属性 title  
  11. TiXmlElement *TitleElement = IdElement->NextSiblingElement();  
  12. //第二个属性的值  
  13. CString nodeTitle = TitleElement->FirstChild()->Value();  
  14. .....................  
  15. 如果还有后续节点,依次读取  
  16. .....................  
  17. 维护读出的数据  
  18. .....................  
  19. //指向下一节点  
  20. CurrentPersonCurrentPerson = CurrentPerson->NextSiblingElement();  

以下是增加xml记录的操作,例如要增加 id 为 300,title 为 test3 的记录:

  1. //创建节点对象  
  2. TiXmlElement *PersonElement = new TiXmlElement("prop");  
  3. //链接到根节点  
  4. RootElement ->LinkEndChild(PersonElement);  
  5. //创建节点对象的属性节点  
  6. TiXmlElement *IdElement = new TiXmlElement("id");  
  7. TiXmlElement *TitleElement =new TiXmlElement("title");  
  8. //将属性节点链接到子节点  
  9. PersonElement->LinkEndChild(IdElement);  
  10. PersonElement->LinkEndChild(TitleElement);  
  11. //创建属性对应数值对象  
  12. TiXmlText *idContent = new TiXmlText("300");  
  13. TiXmlText *titleContent = new TiXmlText("test3");  
  14. //将数值对象关联到属性节点  
  15. IdElement->LinkEndChild(idContent);  
  16. TitleElement->LinkEndChild(titleContent);  
  17. //保存到文件  
  18. myDocument->SaveFile(m_filefullPath.c_str()); 

以下是删除记录操作,例如要删除id为300 的记录:

  1. //获取当前要删除的节点  
  2. TiXmlElement * childElement = 根据id从自己读取时缓存的数据中获得  
  3. //从根节点移除子节点  
  4. RootElement->RemoveChild(childElement);  
  5. //保存文件  
  6. myDocument->SaveFile(m_filefullPath.c_str()); 

学习TinyXML主要是要理解其节点的层次关系,通晓其筋脉,则运用自如。



C++ TinyXml操作(含源码下载)

前言

TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译,使用TinyXML进行C++ XML解析,使用简单,容易上手。
这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。 
DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。

TinyXML介绍

在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的一些操作。

下载和编译

本文运行环境是: Redhat 5.5 + g++version 4.6.1 +  GNU Make 3.81 + tinyxml_2_6_2

下载地址是:http://sourceforge.net/projects/tinyxml/

解压之后得到文件夹tinyxml,tinyxml的头文件和cpp文件,都在这个文件夹,为了我们的管理我们的项目工程,我们还是把tinyxml做一个整理。

由于tinyxml不仅支持Linux编译,同时也支持windows下编译,所以解压之后不仅有h文件,cpp文件,还有vc工程的一些工程文件,这里我们只在Linux上使用,所以只留下h文件和cpp文件,其他文件一概删除

这里我列出整理后的工作目录:

复制代码
tinyxml/           //工作目录|-- include        //头文件根目录|  |-- tinyxml    //tinyxml头文件,包括tinystr.h tinyxml.h|-- src            //cpp源码文件根目录  |-- tinyxml       //tinyxml源码文件夹,包括tinystr.cpp tinyxml.cpp tinyxmlerror.cpp tinyxmlparser.cpp  |-- main.cpp   //我们的主函数,调用tinyxml的示例代码  |-- conf            //我们示例中用的xml文件所在的文件夹|-- makefile       //makefile,不用我们多说了吧,不懂请看我博客的makefile最佳实践
复制代码

 

最简单的例子

我们在conf目录下建立student.xml,xml代码如下:

复制代码
<School name="软件学院">      <Class name = "C++">          <Student name="tinyxml" number="123">              <email>tinyxml@163.com</email>              <address>中国</address>                   </Student>          <Student name="jsoncpp" number="456">              <email>jsoncpp@gmail.com</email>              <address>美国</address>                   </Student>      </Class>  </School>  
复制代码

使用tinyxml,我们只需要在头文件中包含 <tinyxml.h>就行了。

打印整个XML代码如下:

复制代码
void printSchoolXml() {    using namespace std;    TiXmlDocument doc;      const char * xmlFile = "conf/school.xml";       if (doc.LoadFile(xmlFile)) {            doc.Print();      } else {        cout << "can not parse xml conf/school.xml" << endl;    }   }
复制代码

 

读取XML

代码如下:

复制代码
void readSchoolXml() {    using namespace std;    const char * xmlFile = "conf/school.xml";    TiXmlDocument doc;                                  if (doc.LoadFile(xmlFile)) {        doc.Print();    } else {        cout << "can not parse xml conf/school.xml" << endl;        return;    }    TiXmlElement* rootElement = doc.RootElement();  //School元素      TiXmlElement* classElement = rootElement->FirstChildElement();  // Class元素    TiXmlElement* studentElement = classElement->FirstChildElement();  //Students      for (; studentElement != NULL; studentElement = studentElement->NextSiblingElement() ) {        TiXmlAttribute* attributeOfStudent = studentElement->FirstAttribute();  //获得student的name属性          for (;attributeOfStudent != NULL; attributeOfStudent = attributeOfStudent->Next() ) {            cout << attributeOfStudent->Name() << " : " << attributeOfStudent->Value() << std::endl;               }                                         TiXmlElement* studentContactElement = studentElement->FirstChildElement();//获得student的第一个联系方式         for (; studentContactElement != NULL; studentContactElement = studentContactElement->NextSiblingElement() ) {            string contactType = studentContactElement->Value();            string contactValue = studentContactElement->GetText();            cout << contactType  << " : " << contactValue << std::endl;                   }            } }
复制代码

写入xml

这里我们将通过xml写入代码操作,写入几乎和conf/school.xml同样内容到conf/school-write.xml,代码如下:

复制代码
void writeSchoolXml() {    using namespace std;    const char * xmlFile = "conf/school-write.xml";     TiXmlDocument doc;      TiXmlDeclaration * decl = new TiXmlDeclaration("1.0", "", "");      TiXmlElement * schoolElement = new TiXmlElement( "School" );      TiXmlElement * classElement = new TiXmlElement( "Class" );      classElement->SetAttribute("name", "C++");    TiXmlElement * stu1Element = new TiXmlElement("Student");    stu1Element->SetAttribute("name", "tinyxml");    stu1Element->SetAttribute("number", "123");    TiXmlElement * stu1EmailElement = new TiXmlElement("email");    stu1EmailElement->LinkEndChild(new TiXmlText("tinyxml@163.com") );    TiXmlElement * stu1AddressElement = new TiXmlElement("address");    stu1AddressElement->LinkEndChild(new TiXmlText("中国"));    stu1Element->LinkEndChild(stu1EmailElement);    stu1Element->LinkEndChild(stu1AddressElement);    TiXmlElement * stu2Element = new TiXmlElement("Student");    stu2Element->SetAttribute("name", "jsoncpp");    stu2Element->SetAttribute("number", "456");    TiXmlElement * stu2EmailElement = new TiXmlElement("email");    stu2EmailElement->LinkEndChild(new TiXmlText("jsoncpp@163.com"));    TiXmlElement * stu2AddressElement = new TiXmlElement("address");    stu2AddressElement->LinkEndChild(new TiXmlText("美国"));    stu2Element->LinkEndChild(stu2EmailElement);    stu2Element->LinkEndChild(stu2AddressElement);    classElement->LinkEndChild(stu1Element);      classElement->LinkEndChild(stu2Element);      schoolElement->LinkEndChild(classElement);          doc.LinkEndChild(decl);      doc.LinkEndChild(schoolElement);     doc.SaveFile(xmlFile);  }
复制代码

 

下载工程

点击下载

下载之后的编译和运行步骤

unzip tinyxml.zipcd tinyxmlmake./main

 

更多操作

  请参考 http://www.grinninglizard.com/tinyxmldocs/tutorial0.html

 

 

 


0 0
原创粉丝点击