Cocos数据篇[3.4](3) ――XML数据 *** 作

Cocos数据篇[3.4](3) ――XML数据 *** 作,第1张

概述【唠叨】     XML 即 可扩展标记语言,在游戏开发中,常用于保存游戏数据信息,如最高分、游戏等级等信息,和描述一些资源等。     加载动画的plist文件、瓦片地图编辑器到处的地图格式tmx文件,实际上都是特定格式的xml文件。     另外 UserDefault 单例类保存的数据,也是存储在xml文件中的。     Cocos2d-x 已经加入了 tinyxml2库 用于xml的解析。

【唠叨】

XML可扩展标记语言,在游戏开发中,常用于保存游戏数据信息,如最高分、游戏等级等信息,和描述一些资源等。

加载动画的pList文件、瓦片地图编辑器到处的地图格式tmx文件,实际上都是特定格式的xml文件

另外UserDefault单例类保存的数据,也是存储在xml文件中的。

Cocos2d-x 已经加入了 tinyxml2库 用于xml的解析。3.x版本位于external/tinyxml2下。

本节要介绍的就是:如何使用 tinyxml2库 *** 作处理xml文件。


【参考】

http://www.w3school.com.cn/xml/index.asp(W3School)

http://cn.cocos2d-x.org/tutorial/show?id=1225(【官方文档】Cocos2d-x xml解析)

http://www.jb51.cc/article/p-elwdclzu-kt.html(TinyXml 解析 XML)



【XML简介】

摘自:http://www.w3school.com.cn/xml/index.asp


1、什么是XML?

>XML 指可扩展标记语言(EXtensible Markup Language)。

> XML 是一种标记语言,很类似 HTML。

>XML 的设计宗旨是:传输数据,而非显示数据。

>XML 标签没有被预定义,您需要自行定义标签。

>XML 被设计为具有自我描述性。

>XML 是 W3C 的推荐标准。


2、XML的一个例子

先来看一个简单的例子。

//	<?xmlversion="1.0"enCoding="UTF-8"?>	<note>		<to>George</to>		<from>John</from>		<heading>Reminder</heading>		<body>Don'tforgetthemeeting!</body>	</note>//

代码分析:

(1)第一行是 XML 声明。它定义 XML 的版本(1.0)和所使用的编码(UTF-8字符集)。

(2)下一行描述文档的根元素(像在说:“本文档是一个便签”):<note> 。

(3)接下来 4 行描述根元素的 4 个子元素(to,from,heading,body)。

(4)最后一行定义根元素的结尾:</note> 。

以上是一个简单的XML文档。可以发现XML的语法很简单,标签没有被预定义,都是自己定义的标签。并且元素可以有子元素,这就形成了一个树形结构。


3、XML树结构

> XML 文档必须包含根元素,该元素是所有其他元素的父元素。

>所有元素均可拥有 多个子元素

>所有元素均可拥有 文本内容和属性(类似 HTML 中)。

>父、子以及同胞等术语用于描述元素之间的关系:父元素拥有子元素;相同层级上的子元素成为同胞(兄弟或姐妹)。

>XML 文档中的元素形成了一棵文档树的结构。这棵树从“根部”开始,并扩展到树的“枝叶”。

//	<root>		<child1>			<subchild1>.....</subchild1>			<subchild2>.....</subchild2>			.....		</child1>		<child2>			<subchild1>.....</subchild1>			<subchild2>.....</subchild2>			.....		</child2>		.....	</root>//

如下所示,一个树结构的实例:

650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="1.png" alt="wKiol1ThrrvCy2UXAADTKMjl7cM977.jpg" src="http://s3.51cto.com/wyfs02/M00/59/C6/wKiol1ThrrvCy2UXAADTKMjl7cM977.jpg">

它表示了XML中的一本书:

> 根元素是 <bookstore>。文档中的所有 <book> 元素都被包含在 <bookstore> 中 。

> 并且<book> 元素也有 4 个子元素:<Title>、< author>、<year>、<price> 。

> category、lang均为元素的属性。

> <book>的4个子元素。

//	<bookstore>		<bookcategory="COOKING">			<Titlelang="en">EverydayItalian</Title>			<author>GiadaDeLaurentIIS</author>			<year>2005</year>			<price>30.00</price>		</book>		<bookcategory="CHILDREN">			<Titlelang="en">HarryPotter</Title>			<author>JK.Rowling</author>			<year>2005</year>			<price>29.99</price>		</book>		<bookcategory="WEB">			<Titlelang="en">LearningXML</Title>			<author>ErikT.Ray</author>			<year>2003</year>			<price>39.95</price>		</book>	</bookstore>//


4、语法规则

(1)XML 文档必须有根元素

(2)XML 必须有结束标签。( <p>This is a paragraph.</p> )

(3)XML 标签对大小写敏感。(标签 <Letter> 与 <letter> 是不同的)

(4)XML 元素必须被正确的嵌套

//	<!--错误的嵌套-->	<b><i>Thistextisboldanditalic</b></i>	<!--正确的嵌套-->	<b><i>Thistextisboldanditalic</i></b>//

(5)XML 属性值必须加引号。(单引号' '、双引号" " ,均可以

//	<notedate="08/08/2008">	<notedate='08/08/2008'>//


4.1、注释

在 XML 中编写注释的语法与 HTML 的语法很相似:

//	<!--Thisisacomment-->//


4.2、保留空格

HTML会把多个连续的空格字符裁减(合并)为一个。

而在XML中,空格不会被删节。

//	content:HellomynameisDavID.	HTML:HellomynameisDavID.	XML:HellomynameisDavID.//


4.3、实体引用

在 XML 中,一些字符拥有特殊的意义。

如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。

这样会产生 XML 错误:

<message>if salary < 1000 then</message>

为了避免这个错误,请用实体引用来代替 "<" 字符:

<message>if salary &lt; 1000 then</message>

在 XML 中,有 5 个预定义的实体引用:

&lt; < 小于
&gt; > 大于
&amp; &
和号
&apos; '
单引号
&quot; "
双引号


4.4、XML元素

XML 元素指的是从(且包括)开始标签,直到(且包括)结束标签的部分。

> 元素可包含:其他元素、文本、或者两者的混合物。

> 元素也可以拥有属性。

//	<bookstore>		<bookcategory="CHILDREN">			<Title>HarryPotter</Title>			<author>JK.Rowling</author>			<year>2005</year>			<price>29.99</price>		</book>	</bookstore>//

在上例中:

<bookstore> 和 <book> 都拥有元素内容,因为它们包含了其他元素。

<author> 只有文本内容,因为它仅包含文本。

在上例中,只有 <book> 元素拥有属性(category="CHILDREN")。


4.5、XML属性

XML 元素可以在开始标签中包含属性,类似 HTML。属性 (Attribute) 提供关于元素的额外(附加)信息。

属性通常提供:不属于数据组成部分的信息。

在下面的例子中,文件类型与数据无关,但是对需要处理这个元素的软件来说却很重要。

PS:属性的值必须加引号(单引号、双引号,均可以)。

//	<filetype="gif">computer.gif</file>//


4.6、元素 vs. 属性

有时候属性和元素均可以提供相同的信息。

如下所示:

//	<personsex="female">		<name>Alice</name>		</person>	<person>		<sex>female</sex>		<name>Alice</name>	</person>//

这样写虽然可以,但是这样的定义会造成数据的混乱,并且不易阅读(想获取数据信息,到底是访问属性还是元素?)

所以最好的做法是:

>属性:用来提供不属于数据组成部分的信息。如图片格式、书籍分类、ID 索引等。

> 元素:用来描述数据信息。


4.7、元素的命名规则

XML 元素必须遵循以下命名规则:

>名称可以含字母、数字以及其他的字符。

>名称不能以数字或者标点符号开始。

>名称不能以字符 “xml”(或者 XML、Xml)开始。

>名称不能包含空格。

可使用任何名称,没有保留的字词。


XML元素的命名习惯:

>使名称具有描述性。使用下划线的名称也很不错。

>名称应当比较简短,比如:<book_Title>,而不是:<the_Title_of_the_book>。

>避免 "-" 字符。如果按照这样的方式命名:"first-name",一些软件会认为你需要提取第一个单词。

>避免 "." 字符。如果按照这样的方式命名:"first.name",一些软件会认为"name"是对象"first"的属性。

>避免 ":" 字符。冒号会被转换为命名空间来使用。



【tinyxml2】

Cocos2d-x 已经加入了 tinyxml2库 用于xml的解析。

3.x版本位于external/tinyxml2下。


0、相关类

XMLNode :表示一个节点,包含一般方法,如访问自节点、兄弟节点、编辑自身、编辑子节点。

XMLdocument :表示整个XML文档,不对应其中某个特定的节点。

XMLElement :表示元素节点,可以包含子节点XMLElement、和属性XMLAttribute。

XMLAttribute :表示一个元素的属性。

XMLText :表示文本节点。

XMLComment :表示注释。

XMLDeclaration :表示声明。


1、添加头文件

//	#include"tinyxml2/tinyxml2.h"	usingnamespacetinyxml2;//


2、XML数据解析

XML文档如下:

//	<?xmlversion="1.0"enCoding="UTF-8"?>	<person>		<studentID="1111">			<name>Alice</name>			<age>20</age>		</student>		<teacherID="2222">			<name>Bob</name>			<age>30</age>		</teacher>	</person>//

XML解析使用举例:

////[0]文件路径	std::stringpath="/soft/cocos2d-x-3.4/projects/Demo34/Resources/testXML.xml";//[1]创建管理XML文档的对象:XMLdocument	XMLdocument*doc=newXMLdocument();//[2]解析xml文件	//方式一:	//Datadata=fileUtils::getInstance()->getDataFromfile(path.c_str());	//XMLErrorerrorID=doc->Parse((constchar*)data.getBytes());	//方式二:	//std::stringdata=fileUtils::getInstance()->getStringFromfile(path.c_str());	//XMLErrorerrorID=doc->Parse(data.c_str());	//方式三:	XMLErrorerrorID=doc->Loadfile(path.c_str());//[3]判断是否解析错误	if(errorID!=0){		cclOG("ParseError!");		return;	}//[4]获取根元素<person>	XMLElement*root=doc->RootElement();//[5]获取子元素信息	//[5.1]遍历root的子元素<student>,<teacher>	//FirstChildElement():获取root的第一个子元素	//NextSiblingElement():获取chd的下一个兄弟元素	for(XMLElement*chd=root->FirstChildElement();chd;chd=chd->NextSiblingElement()){		//[5.2]获取子元素名称		cclOG("chd:%s",chd->name());		//[5.3]遍历子元素的属性ID		//FirstAttribute():获取chd元素的第一个属性		//Next():获取chd元素的attr属性的下一个属性		for(constXMLAttribute*attr=chd->FirstAttribute();attr;attr=attr->Next()){			//name():属性名称			//Value():属性值			cclOG("chd_attr:%s,%s",attr->name(),attr->Value());		}		//也可以通过属性名称,来获取属性值		//cclOG("ID=%s",chd->Attribute("ID"));		//[5.4]遍历子元素chd的子元素<name>,<age>		for(XMLElement*e=chd->FirstChildElement();e;e=e->NextSiblingElement()){			//子元素e为文本内容			//GetText():文本内容			cclOG("e:%s,e->name(),e->GetText());		}	}//[6]释放内存	deletedoc;//

控制台输出结果:

650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="5.png" alt="wKiol1Th_FeCLYSQAABFZ3mXVwI289.jpg" src="http://s3.51cto.com/wyfs02/M00/59/C7/wKiol1Th_FeCLYSQAABFZ3mXVwI289.jpg">


3、XML数据存储

以上面解析的XML文档为例,我们通过代码来生成相应的XML文档,并保存到xml文件中。

生成XML文档并保存,举例:

////[0]文件路径	std::stringpath="/soft/cocos2d-x-3.4/projects/Demo34/Resources/testXML.xml";//[1]创建管理XML文档的对象:XMLdocument	XMLdocument*doc=newXMLdocument();//<!--begin-->//[2]创建XML声明,并连接到XML文档中	XMLDeclaration*declare=doc->NewDeclaration("xmlversion=\"1.0\"enCoding=\"UTF-8\"");	doc->linkEndChild(declare);//添加到文档尾部//[3]创建注释,并连接到XML文档中	XMLComment*comment=doc->NewComment("thisisxmlcomment");	doc->linkEndChild(comment);//[4]创建根节点,并连接到XML文档	XMLElement*root=doc->NewElement("person");	doc->InsertEndChild(root);//与linkEndChild()功能相同//[5]创建两个子元素,并连接到root元素中,作为root的子节点	XMLElement*student=doc->NewElement("student");	XMLElement*teacher=doc->NewElement("teacher");	root->linkEndChild(student);//添加到root子元素中	root->linkEndChild(teacher);//添加到root子元素中//[6]设置/添加<student>、<teacher>的属性值	student->SetAttribute("ID","1111");	teacher->SetAttribute("ID","2222");//[7]创建子元素,并连接到<student>、<teacher>元素中,作为子节点	XMLElement*name1=doc->NewElement("name");	XMLElement*name2=doc->NewElement("name");	XMLElement*age1=doc->NewElement("age");	XMLElement*age2=doc->NewElement("age");	student->linkEndChild(name1);	student->linkEndChild(age1);	teacher->linkEndChild(name2);	teacher->linkEndChild(age2);//[8]创建文本内容,并添加到<name>、<age>元素中,作为文本内容	XMLText*name1_text=doc->NewText("Alice");	XMLText*name2_text=doc->NewText("Bob");	XMLText*age1_text=doc->NewText("20");	XMLText*age2_text=doc->NewText("30");	name1->linkEndChild(name1_text);	name2->linkEndChild(name2_text);	age1->linkEndChild(age1_text);	age2->linkEndChild(age2_text);//<!--ended-->//[9]保存XMLdocument数据到XML文档中	doc->Savefile(path.c_str());//[10]释放内存	deletedoc;//

运行程序后,生成的XML文档如下:

650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="6.png" alt="wKiol1TiBU2zxfGcAADPDd8XuuQ334.jpg" src="http://s3.51cto.com/wyfs02/M00/59/C7/wKiol1TiBU2zxfGcAADPDd8XuuQ334.jpg">


4、XML数据修改

以上面存储的XML文档为例,进行数据的修改 *** 作。

原始XML文档数据如下:

650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="6.png" alt="wKiol1TiBU2zxfGcAADPDd8XuuQ334.jpg" src="http://s3.51cto.com/wyfs02/M00/59/C7/wKiol1TiBU2zxfGcAADPDd8XuuQ334.jpg">

XML文档数据修改,举例:

////[0]文件路径	std::stringpath="/soft/cocos2d-x-3.4/projects/Demo34/Resources/testXML.xml";//[1]创建管理XML文档的对象:XMLdocument	XMLdocument*doc=newXMLdocument();//[2]解析xml文件	XMLErrorerrorID=doc->Loadfile(path.c_str());//[3]判断是否解析错误	if(errorID!=0){		cclOG("ParseError!");		return;	}//[4]获取根元素<person>	XMLElement*root=doc->RootElement();//[5]获取子元素<student>、<teacher>	XMLElement*student=root->FirstChildElement();	XMLElement*teacher=student->NextSiblingElement();//<!--begin-->//[6]修改数据	//[6.1]添加新元素<city>	XMLElement*city=doc->NewElement("city");	XMLText*city_text=doc->NewText("北京");	city->linkEndChild(city_text);	student->linkEndChild(city);	//[6.2]添加新属性<type>	root->SetAttribute("type","学校人群");	//[6.3]修改元素名称	student->Setname("学生");	//[6.4]修改属性值	student->SetAttribute("ID","9999");	//[6.5]删除元素	root->DeleteChild(teacher);//<!--ended-->//[7]保存XMLdocument修改后的数据,到XML文档中	doc->Savefile(path.c_str());//[8]释放内存	deletedoc;//

运行程序后,修改后的XML文档如下:

650) this.wIDth=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="8.png" alt="wKiom1TiCRKzI94aAAC_hEPMSVU422.jpg" src="http://s3.51cto.com/wyfs02/M01/59/CA/wKiom1TiCRKzI94aAAC_hEPMSVU422.jpg">



【常用数据 *** 作】

这里介绍一下常用的4个类的使用方法。

> XMLNode :表示一个节点,包含一般方法,如访问自节点、兄弟节点、编辑自身、编辑子节点。

> XMLdocument :表示整个XML文档,不对应其中某个特定的节点。

> XMLElement :表示元素节点,可以包含子节点XMLElement、和属性XMLAttribute。

> XMLAttribute :表示一个元素的属性。


1、XMLNode

表示一个节点,包含一般方法,如访问自节点、兄弟节点、编辑自身、编辑子节点。

PS:它是 XMLdocument、XMLElement、XMLAttribute 的父类。

常用方法如下:

////获得该XMLNode节点所在的XMLdocument文档	XMLdocument*Getdocument();//获取'value'值	//	document:空	//	Element:元素名称	//	Comment:注释内容	//	Text:文本内容	constchar*Value();//设置Node节点的value值	voIDSetValue(constchar*val);//获取关联节点	//获取父节点	XMLNode*Parent();	//获取第一个子节点,若没有返回null	//获取最后一个子节点,若没有返回null	//获取前一个兄弟节点	//获取下一个兄弟节点	XMLNode*FirstChild();	XMLNode*LastChild();	XMLNode*PrevIoUsSibling();	XMLNode*NextSibling();	//获取第一个子元素	//获取最后一个子元素	//获取前一个兄弟元素	//获取下一个兄弟元素	XMLElement*FirstChildElement();	XMLElement*LastChildElement();	XMLElement*PrevIoUsSiblingElement();	XMLElement*NextSiblingElement();//插入子节点	//放在最前面	XMLNode*InsertFirstChild(XMLNode*addThis);	//放在最后面	XMLNode*InsertEndChild(XMLNode*addThis);	XMLNode*linkEndChild(XMLNode*addThis){returnInsertEndChild(addThis);}	//放在指定afterThis子节点的后面	XMLNode*InsertAfterChild(XMLNode*afterThis,XMLNode*addThis);//删除子节点	//删除所有子节点	voIDDeleteChildren();	//删除指定node子节点	voIDDeleteChild(XMLNode*node);//


2、XMLdocument

表示整个XML文档,不对应其中某个特定的节点。

PS:父类为XMLNode,拥有父类所有的方法,这里不再赘述。

////解析xml串,需要先通过fileUtils类获取xml文件的内容串	XMLErrorParse(constchar*xml);//解析xml文件	XMLErrorLoadfile(constchar*filename);//将XMLdocument的xml内容保存到filename文件中	XMLErrorSavefile(constchar*filename);//获取根节点	XMLElement*RootElement(){returnFirstChildElement();}//新建	//元素<a></a>	XMLElement*NewElement(constchar*name);	//注释<!--...-->	XMLComment*NewComment(constchar*comment);	//文本内容helloworld	XMLText*NewText(constchar*text);	//声明<?...?>	//	如:<?xmlversion="1.0"enCoding="UTF-8"?>	XMLDeclaration*NewDeclaration(constchar*text=0);//删除	//删除指定节点	voIDDeleteNode(XMLNode*node){node->_parent->DeleteChild(node);}//


3、XMLElement

表示元素节点,可以包含子节点XMLElement、和属性XMLAttribute。

PS:父类为XMLNode,拥有父类所有的方法,这里不再赘述。

////获取/设置元素名称,等价于Value	constchar*name(){returnValue();}	voIDSetname(constchar*str){SetValue(str,staticmem);}//获取元素的文本内容,若没有返回空	constchar*GetText()const;	//获取指定名称属性的属性值	constchar*Attribute(constchar*name);//字符串	boolBoolAttribute(constchar*name);//bool	intIntAttribute(constchar*name);//int	unsignedUnsignedAttribute(constchar*name);//unsignedint	floatfloatAttribute(constchar*name);//float	doubleDoubleAttribute(constchar*name);//double//获取第一个属性	constXMLAttribute*FirstAttribute();//获取指定名称属性	constXMLAttribute*FindAttribute(constchar*name);//设置属性	voIDSetAttribute(constchar*name,constchar*value);	voIDSetAttribute(constchar*name,boolvalue);	voIDSetAttribute(constchar*name,intvalue);	voIDSetAttribute(constchar*name,unsignedvalue);	voIDSetAttribute(constchar*name,doublevalue);//删除指定属性	voIDDeleteAttribute(constchar*name);//


4、XMLAttribute

表示一个元素的属性。

没有父类。

常用方法如下:

////获取属性名称	constchar*name();//获取下一个属性	//该属性对应的元素中,定义在该属性后面的属性	XMLAttribute*Next();//获取属性值	constchar*Value();	boolBoolValue();	intIntValue();	unsignedintUnsignedValue();	floatfloatValue();	doubleDoubleValue();//设置属性值	voIDSetAttribute(constchar*value);	voIDSetAttribute(boolvalue);	voIDSetAttribute(intvalue);	voIDSetAttribute(unsignedintvalue);	voIDSetAttribute(floatvalue);	voIDSetAttribute(doublevalue);//
总结

以上是内存溢出为你收集整理的Cocos数据篇[3.4](3) ――XML数据 *** 作全部内容,希望文章能够帮你解决Cocos数据篇[3.4](3) ――XML数据 *** 作所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1040405.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存