【iOS-cocos2d-X 游戏开发之九】Cocos2dx利用CCSAXParser解析xml数据&CCMutableDictionary使用与注意!

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

          ☞ 点击订阅 ☜
 本博客最新动态!及时将最新博文通知您!

本章Himi给大家分享如何在Cocos2dX中解析xml数据;对于数据存取有很多方式,流文件,plist,xml等,那么为了跨平台更好的支持,Himi想到之前写的CCUserDefault 存储数据一节,Cocos2dx自带的存储类,一旦存入数据都会以xml格式进行保存,适用于iOS、Android等平台,所以这里Himi使用xml进行游戏的一些数据录入  = =.. 另外一方面Himi本章节也是基于Cocos2dx引擎代码进行的一次简单对xml数据解析的封装;

为了更保险的去考虑跨平台,所以对于xml存储这块的解析,也做了些搜索,最后发现王哥(王哲-cocos2dx引擎作者)也有给我们提示过,内容如下:

1
2
3
cocos2dx里面集成了libxml2,ios上会调用sdk里面内置的,
android和win32上则带了已经编译好的静态/动态库。
你可以参考CCSAXParser里面的代码来使用libxml2

那么既然如此,就对Cocos2dx引擎源码的CCSAXParser类进行了剖析,那么这里Himi,先给出代码,然后再详细讲解下:

Himi封装的HXmlParse类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
HXmlParse.h
 
//
//  HXmlParse.h
//  HAnimation
//
//  Created by Himi on 12-3-22.
//  Copyright (c) 2012年 Augustimpression. All rights reserved.
//
 
#ifndef HAnimation_HXmlParse_h
#define HAnimation_HXmlParse_h
 
#include "cocos2d.h"
#include "CCSAXParser.h"
#include "CCObject.h"
#include "CCMutableDictionary.h"
 
using namespace cocos2d;
 
class CC_DLL HXmlParse : public CCObject, public CCSAXDelegator
{
 
public :
 
     static HXmlParse * parserWithFile( const char *tmxFile);
 
     bool initHXmlParse( const char * xmlName);
 
     //  使用 CCSAXDelegator 重写3个回调函数
 
     void startElement( void *ctx, const char *name, const char **atts);
 
     void endElement( void *ctx, const char *name);
 
     void textHandler( void *ctx, const char *ch, int len);
 
     std::string root_name;
 
     bool isJumpHeadData;
 
     CCMutableDictionary<std::string,CCString*> *mDic;
 
private :
 
     std::string startXmlElement; //用来记录每个key前字段
 
     std::string endXmlElement; //用来记录每个key后字段
 
     std::string currString; //记录每个value的值
 
};
 
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
HXmlParse.cpp
 
//
//  HXmlParse.cpp
//  HAnimation
//
//  Created by Himi on 12-3-22.
//  Copyright (c) 2012年 Augustimpression. All rights reserved.
//
 
#include "HXmlParse.h"
#include "CCSAXParser.h"
 
HXmlParse * HXmlParse::parserWithFile( const char *tmxFile)
{
     HXmlParse *pRet = new HXmlParse();
     if (pRet->initHXmlParse(tmxFile))
     {
         pRet->autorelease();
         return pRet;
     }
     CC_SAFE_DELETE(pRet);
     return NULL;
}
 
bool HXmlParse::initHXmlParse( const char * xmlName)
 
{
 
     mDic = new CCMutableDictionary<std::string,CCString*>();
 
     CCSAXParser _par; 
 
     if ( false == _par.init( "UTF-8" ) )
 
     {
         CCLog( "-----请使用utf-8格式!" );
         return false ;
     }
     _par.setDelegator( this );
     const char * _path =CCFileUtils::fullPathFromRelativePath(xmlName);
     return _par.parse(_path);
 
}
 
//回调函数
 
void HXmlParse::startElement( void *ctx, const char *name, const char **atts)
 
{  
 
     CC_UNUSED_PARAM(ctx);
 
     startXmlElement = ( char *)name;
     if (!isJumpHeadData){ //跳过数据头
         CCLog( "------跳过root name" );
         isJumpHeadData= true ;
         root_name=startXmlElement;
         return ;
     }
 
//    CCLog("-startElement----%s",startXmlElement.c_str());
 
}
 
void HXmlParse::endElement( void *ctx, const char *name)
 
{
     CC_UNUSED_PARAM(ctx);
 
     endXmlElement = ( char *)name;
     if (endXmlElement==root_name){ //数据尾
         CCLog( "读取xml结束" );
         isJumpHeadData= false ;
         root_name= "" ;
         return ;
     }
 
//    CCLog("-endElement----%s",endXmlElement.c_str());
}
//键值对的结束字段
void HXmlParse::textHandler( void *ctx, const char *ch, int len)
{
 
     CC_UNUSED_PARAM(ctx);
     currString=string(( char *)ch,0,len);
     CCString *ccStr = new CCString(); //备注3
     ccStr->m_sString=currString;
     if (root_name!= "" ){
          mDic->setObject(ccStr,startXmlElement);
         CCLog( "-----key:%s, value:%s" ,startXmlElement.c_str(),mDic->objectForKey(startXmlElement)->m_sString.c_str());
     }
 
//    CCLog("-textHandler----%s",currString.c_str());
 
}

OK,代码呢我们先从.h中来说,首先我们使用CCSAXDelegator,为了让CCSAXParser解析数据后将数据回调给如下三个函数:

1
2
3
4
5
6
7
//  使用 CCSAXDelegator 重写3个回调函数
 
    void startElement( void *ctx, const char *name, const char **atts);
 
    void endElement( void *ctx, const char *name);
 
    void textHandler( void *ctx, const char *ch, int len);

startElement   函数解析的是xml的每个key前字段

textHandler  函数解析出来的是xml每个key对应的value值

endElement   函数解析出来的是xml的每个key后字段

这里Himi随便写了一个xml来做测试,himi.xml,如下:

1
<?xml version= "1.0" encoding= "utf-8" ?><himiTestData><key1>1000</key1><key2>娃哈哈</key2><key3>82.3</key3><key4>4000</key4><key5>himi</key5><key6> true </key6></himiTestData>

那么CCSAXParser类解析第一次回调 startElement 是读取的是root name(xml数据头标识名称->“<himiTestData>”),然后才读取正式数据key和value,最后读取的也是xml数据尾标识名称“</himiTestData>”

当然在Himi封装的HXmlParse类中对于数据标识的读取都跳过了,使用变量isJumpHeadData来处理的;

其他的都很容易没有什么可说的,主要要说还有一点就是关于CCMutableDictionary的使用,对于此类主要结构是形成map&NSMutableDictionary类似是个键值对容器,key-value;那么使用时候要注意4点:

1.  比如Himi解析数据后都会默认将key和value数据存放在CCMutableDictionary中,那么这里我肯定传入的是两个string,但是细心的童鞋会发现代码中第二个并不是std::string,而是CCString对象,嗯 没错,CCMutableDictionary要求传入的是CCObject对象而不是基本类型!CCString中有m_sString这个属性,所以转换起来也是很方便的;

2. 使用CCMutableDictionary进行添加数据setObject的时候要注意此函数的两个参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
bool setObject(_ValueT pObject, const _KeyT& key)
     {
         pair<CCObjectMapIter, bool > pr;
 
         pr = m_Map.insert( Int_Pair(key, pObject) );
 
         if (pr.second == true )
         {
             pObject->retain();
             return true ;
         }
 
         return false ;
     }

上面这个是cocos2dx引擎中源码中setObject函数实现代码,这里可以很清晰的看到,第一个参数表示《CCObject》,第二个参数才是《Key》!这点对于之前做过java开发的我来说比较郁闷,因为一般都是key在第一个参数。。。。。

3. 请大家仔细看HXmlParse.cpp类中的备注3 ,当你使用CCMutableDictionary的setObject函数的时候,务必要注意,此函数的存入的CCObject参数,引擎中实现代码是对你这个CCObject进行retain()的一个内存地址引用!也就是说这里不要使用一个成员变量来使用,否则你从CCMutableDictionary取出来的数据全部是你最后一个CCObject数据!

4. CCMutableDictionary是cocos2d-x自己封装的类,功能类似NSMutableDictionary。但是Himi通过测试发现!它有一点和NSMutableDictionary是不一样的。NSMutableDictionary的setObjectForKey方法是:如果发现这个key已经存在于字典中的时候,它会自动用新的object覆盖掉原有的object。而CCMutableDictionary由于它是使用map实现的字典功能,而在map里面,如果key已存在,是不会用新的object覆盖掉原有object的。在使用CCMutableDictionary的时候需要特别注意这一点。

HXmlParse解析xml类使用方法很简单:

1
2
3
#include "HXmlParse.h"
 
HXmlParse::parserWithFile( "himi.xml" );

然后Himi为了证实此解析类在Android也可以正常运行,那么这里Himi将读出的数据展示在画面上,iOS运行截图如下:

 


cocos2dx 3.3 TMX系列简单分析 位置:coco2d/2d/CCTMX 关于TiledMap 一般使用Tile工具来制作地图 生成tmx文件,map包含多个layer、object,layer内包含tile,tile存储为gid tmx文件其实最终也是xml形式的 从CCTMXXMLParser入手 TMXLayerInfo 层信息,包含各种附加属性值,以及基本属性,比如name、size、offset 阅读详情

相关推荐

2026年最新温岭市公交线路矢量数据.zip

数据格式:shp 数据坐标:GCJ02 数据更新时间:2026年9月 公交线路来源:8684网站 https://8684.com.cn/ 站点数据来源:高德API接口 数据打开方式:QGIS或Arcgis 站点数据字段:名称、序号、对应线路、几何信息 线路数据字段:名称、类型、起点、终点、开始时间、结束时间、起步价、全价、长度、公司、几何信息

iOS-cocos2d-X 游戏开发Cocos2dx利用CCSAXParser解析xml数据&CCMutableDictionary使用注意!...

本站文章均为李华明Himi原创,转载务必在明显处注明:转载自【黑米GameDev街区】原文链接:http://www.himigame.com/iphone-cocos2dx/694.html          ☞ 点击订阅 ☜本博客最新动态!及时将最新博文通知您! 本章Himi给大家分享如何在Cocos2dX解析xml数据;对于数据存取有很多方式,流文件,plist,xml等,那么为了跨平...

mmdev 182

Axure PR10和RunAsDate

Axure10用于查看原型设置,旧版10 支持“时间回拨”绕过试用期限制。

cocos2d-x 3.0 使用Sax解析xml文件(中国显示器问题解决)

今天是个好日子。我以为事情可以变得,明天是个好日子。打开门儿春风。。。 恩,听着歌写文档生活就是这么享受。 今天曾经的邻居大神突然在qq上赞了我一下,这让我异常激动啊。。这还要从前前前几天说起,那会无意间看到cocos微信上的一个实话实说活动。反正就是參加了能够抽奖这样子啦。没错。我就是本着那官方T恤去的,本着分子越大分母越大抽奖几率越大的原则,然后就连着发了一番感慨。并且还...

aofan9566的博客 192

Cocos2dx利用CCSAXParser解析XML数据

Cocos2dx利用CCSAXParser解析XML数据 1.、准备素材(xml文件) testExcel.xml 1000娃哈哈82.34000himitrue 2.实现代码: 解析XML类:HXmlParse类 HXmlParse.h #ifndef __cocos2d_x_Excel__HXmlParse__ #define _

小枫的专栏 3161

cocos2d-js官方文档】十三、CCSAXParser.js

cc.saxParser 将cc.SAXParser重构为单例对象:cc.saxParser 删除了tmxParse,preloadPlist,unloadPlist,getName,getExt, getList等方法。 Parser的统一入口函数规范为parse,并且传参内容即为需要解析的文本内容。 cc.plistParser 添加了cc.plistPa

qinning199的专栏 1689

cocos2d-x节点(CCSAXParser.h)API

本文来自http://blog.csdn.net/runaying ,引用必须注明出处! cocos2d-x节点(CCSAXParser.h)API 温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 Cocos2d-X权威指南笔记 SAX解析器 ///cocos2d-x-3.0alpha0/cocos2dx/platform //SAX解析器 #i

runaying的专栏 1606

IOS-COCOS2D-X 游戏开发COCOS2DX利用CCSAXPARSER解析XML数据&CCMUTABLEDICTIONARY使用注意!...

本站文章均为李华明Himi原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接:http://www.himigame.com/iphone-cocos2dx/694.html 本章Himi给大家分享如何在Cocos2dX解析xml数据;对于数据存取有很多方式,流文件,plist,xml等,那么为了跨平台更好的支持,Him...

weixin_34343689的博客 92

Cocos2dx利用CCSAXParser解析xml数据&CCMutableDictionary

iOS-cocos2d-X 游戏开发Cocos2dx利用CCSAXParser解析xml数据&CCMutableDictionary使用注意! 分类: 【 Cocos2dX 游戏开发】2012-04-23 10:41 6700人阅读 评论(5) 收藏 举报 xml游戏stringobject引擎android 本站文章均为 李华明Himi 原

我的 547

Cocos2d-x 3.x版本中SAX 解析 XML

解析xml文件有两种方式:Dom和SAX 按照网上的说法,SAX的解析速度比较快

路飞小迷弟的博客 583

Cocos2d-x游戏引擎开发笔记(25)】XML解析

原创文章,转载请注明出处:http://blog.csdn.net/zhy_cheng/article/details/9128819 XML是一种非常重要的文件格式,由于C++对XML的支持非常完善,cocos2d-x选择XML作为主要的文件存储格式。在cocos2d-x中集成了libxml2来解析XML数据。   定义一个用于解析的类,这个类继承CCSAXDelegator和CCObje

卡尔 8062

cocos2dx --tinyxml2 学习笔记

总结: tinyxml2 不能解析外部自定义引用实体,只能解析数字实体和内置实体,这些实体的解析在封装的字符 串类StrPair对象中;CCDictMaker 不对节点元素的属性进行处理。 1. CCDictMaker 功能:根据Plist类型文件中,数据创建并返回一个 CCDictionary | CCArray 对象。 描述:该类继承了CCSAXDelegator 代理

Jchn lau 1781

cocos2d-x初探学习笔记(27)--CCMutableArray

小满(bill man)个人原创,欢迎转载,转载请注明地址,小满(bill man)的专栏地址http://blog.csdn.net/bill_man 在写cocos2d-x游戏示例的时候,如果发现一些在初探笔记中的遗漏之处,我会随时补充上来,今天补充的就是cocos2d-x中带有的vector----CCMutableArray,我很推荐在cocos2d-x引擎中不使用vector,而是直接...

编程资料大全 160

cocos2d-x -- CCSAXParser笔记

CCSAXParser是异步解析的,而自带的libxml2库是同步解析的。 使用CCSAXParser,就要继承它,并实现startElement / endElement / textHandler三个函数,如 void HelloWorld::startElement(void *ctx, const char *name, const char **atts) { if(atts){

Norton的专栏 1463

jni/../../Classes/AppDelegate.cpp:29: error: undefined reference to 'StartLayer。而且没生成libgame.so文件

分类: cocos2d-x环境搭建常见问题2014-01-23 15:05 304人阅读 评论(0) 收藏 举报 报错。 G:/AndroidCocos2dxFile/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androide

Jingle的专栏 7559

Cocos2D-x游戏开发之二十四:自定义字符串分割类

今天我们为下一节的CSV文件处理做一个准备,开始自定义一个对字符串按照特定的符号分割的类,实现如下: class StringUtil : public CCObject { public: static StringUtil* sharedStrUtil(); bool init(); /** 用分隔符分割字符串,结果存放到一个列表中,列表中的对象为CCString

vanileo的专栏 5061

利用SAXParser对XML文档进行解析处理

    SAXParser因为其对文档的处理方式,致使其可以对大型文档进行有效的处理,并且不会占用服务器太大的内存,故而可以选用这一方式对大型文档进行解析。以下为示例:模拟解析数据&lt;student&gt; &lt;id&gt;1&lt;/id&gt; &lt;name type="chinese"&gt;小明&lt;/name&gt; &lt;/student&gt; &lt;s

KeepMoving00的博客 1126
上一篇: 【Cocos2d-x游戏引擎开发笔记(25)】XML解析
下一篇: 如何解决c++中循环包含头文件的问题
linking530
博客等级 码龄17年 72粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值