TinyXML学习笔记:解析

来源:互联网 发布:网络英雄洛克人粤语版 编辑:程序博客网 时间:2024/05/19 20:47

用C++解析XML一直用的tinyxml,轻便,简单。这里记录下一些自己的使用方法与心得。

对于用tinyxml解析xml,我一般只有三个步骤:

  1. 加载
  2. 获取节点
  3. 读取内容

1.加载

Tinyxml是由一堆类构成的,而加载用到的类是TiXmlDocument。要解析目标XML前都要将目标XML加载到TiXmlDocument对象中,之后的所有操作都将从TiXmlDocument对象出发,包括目标字符串和文件。

加载字符串用LoadFile(const char* buf);

加载文件用Parse(const char* filename);

具体的可去看函数声明

如下,是个有个简单的文档,存于名为class.xml的文档中


<?xml version="1.0" encoding="UTF-8" ?>  <class> <student ID="1" ID2="test"> <Sex>男</Sex>  <Name>班长</Name>  </student>  <student ID="2">无</student>  </class>

我创建一个TiXmlDocument,差加载此文档,以下备用,当然如果是从网络或是别处传入的,只要直接传入内存地址指针就成了。

TiXmlDocument* doc = new TiXmlDocument(); doc->LoadFile("./class.xml");

当然,在使用前最重要的判断指针是否为NULL,之后讲的东西也一样,这是很重要的一点。

if(doc == NULL){return;}

2.获取节点

当加载完成了,便开始解析了,而解析的过程,无非是从一个节点元素开始,往两个方面走,一个向子节点方向深入,一个往兄弟节点平移,而根据需求决定要不要取节点的值。一会详述。

首先我们解析下xml声明,而声明中有用的便是 编码方式。TiXmlDeclaration类表示声明,从doc中通过ToDeclaration()获得,而编码方式则是decl的Encoding(),返回的是const char*;

//获取文档的声明 TiXmlDeclaration* decl = doc->ToDeclaration(); if ( NULL != decl ) { std::string encoding = decl->Encoding(); //这里会返回“UTF-8" }

接下来,开始解析元素。一般XML都有一个根元素,根元素是所有元素的父元素。根元素可以由以下方法获得:
TiXmlElement* root = doc->RootElement();

这个方法可以获得根元素,此元素便是<class>了。

TiXmlElement类,表示元素类,是解析过程中的用的最多的一个类,可以表示所有<>内的元素,当然包括根元素。这里root是指向根元素,而如果你并不知道根元素的名称,可以能过root->Value()获得。而如果你知道这个XML文件的根节点名,笔者用XML一般做传输协议,基本都是知道整个XML的结构的,我推荐另一个方法获取根节点。

TiXmlElement* NodeRoot = doc->FirstChildElement("class");

上行代码表示获取doc的第一个class子节点,因为一开始我们就知道这个XML是以<class>为根节点,这样做不仅可以获取根节点,而且可以验证是不是以class为根节点的。

获取根节点成功后,接下来便是获取student节点了:

//不知道具体节点名 TiXmlElement* NodeStudent = NodeRoot->FirstChildElement();std::cout << NodeStudent->Value << std::endl; //这里输出节点名,即student //知道节点名 TiXmlElement* NodeStudent = NodeRoot->FirstChildElement("student");

当前NodeStrudnt是指向<student ID="1" ID2="test">,而ID,ID2是元素student的属性,“1“,”test"是属性的值,下方的<sex><name>是子节点,也是元素。

想要获取ID=1可用以下代码

TiXmlAttribute* attr = NodeStudent->FirstAttribute(); if(NULL != attr) { std::cout << attr->Name() << endl; //这时输出ID std::cout << attr->Value() << endl; //这里输出1 } attr = attr->Next(); //这里指向第二个属性,attr->Next()操作时是不会自增长的,只是返回下一个属性,所以还要自己赋值 std::cout << attr->Value(); //这里当没有ID2属性时,会抛出异常
想要获得<Sex>只能通过父节点获得,而<Name>则可以同时通过兄弟节点获得
//先通过父节点获取 //不知道具体节点名,指向<Sex> TiXmlElement* NodeSex = NodeStudent->FirstChildElement(); //知道节点名,指向<class> TiXmlElement* NodeName = NodeStudent->FirstChildElement("Name"); //通过兄弟节点指向<class> TiXmlElement* NodeName = NodeSex->NextSiblingElement(); TiXmlElement* NodeName = NodeSex->NextSiblingElement("Name");

而如果想获得节点里的文本信息,可以通过以下方法获得,当然得是元素不为NULL的情况下
//1.可以通过GetText,缺点是当文本信息为空时,会抛了异常 std::cout << NodeSex->GetText() << endl; //输出“男” std::cout << NodeName->GetText() << endl; //输出“班长“ //2.可以过能GetChild判断是否有子文本,然后通过Value()获得 TiXmlNode* text = nodeSex->FirstChild(); if( NULL != text) std::cout << text.Value() <<endl; //输出”男“

如果有很多学生要遍历都可以
while(NULL != NodeStudent) { ...//相应的解析,取值   NodeStudent= NodeStudent->NextSiblingElement("stduent"); }

3.获取内容

第二部分好像已经讲过了,再总结下

获取元素名为  Value()

获取属性名 Name(),属性值Value()

获取文本信息:GetText(),这里要注意不能为空或者通过TiXmlNode的Value获取

 

以上,就是本人解析XML的常用方法,初稿,之后有时间再编辑修改,  BY  WenHY  无氏木

注意点:

1.XML是大小写区分的

2.一定要注意检察获取的东西是否为空

3.最后要释放doc

 






原创粉丝点击