<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                本站文章均為[?李華明Himi?](http://www.himigame.com/about-himi)原創,轉載務必在明顯處注明: 轉載自[【黑米GameDev街區】](http://www.himigame.com/)?原文鏈接:?[http://www.himigame.com/iphone-cocos2dx/694.html](http://www.himigame.com/iphone-cocos2dx/694.html "【iOS-cocos2d-X") [? 點擊訂閱 ?](http://list.qq.com/cgi-bin/qf_invite?id=acfc24e272cc4a26debf3b3866edb626a9ea3fc80fd8893c)?本博客最新動態!及時將最新博文通知您! 本章Himi給大家分享如何在Cocos2dX中解析xml數據;對于數據存取有很多方式,流文件,plist,xml等,那么為了跨平臺更好的支持,Himi想到之前寫的CCUserDefault 存儲數據一節,Cocos2dx自帶的存儲類,一旦存入數據都會以xml格式進行保存,適用于iOS、Android等平臺,所以這里Himi使用xml進行游戲的一些數據錄入 ?= =.. 另外一方面Himi本章節也是基于Cocos2dx引擎代碼進行的一次簡單對xml數據解析的封裝; 為了更保險的去考慮跨平臺,所以對于xml存儲這塊的解析,也做了些搜索,最后發現王哥(王哲-cocos2dx引擎作者)也有給我們提示過,內容如下: ~~~ cocos2dx里面集成了libxml2,ios上會調用sdk里面內置的, android和win32上則帶了已經編譯好的靜態/動態庫。 你可以參考CCSAXParser里面的代碼來使用libxml2 ~~~ 那么既然如此,就對Cocos2dx引擎源碼的CCSAXParser類進行了剖析,那么這里Himi,先給出代碼,然后再詳細講解下: Himi封裝的HXmlParse類: ~~~ 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 ~~~ ~~~ 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解析數據后將數據回調給如下三個函數: ~~~ // 使用 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,如下: ~~~ <?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的時候要注意此函數的兩個參數: ~~~ 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類使用方法很簡單: ~~~ #include "HXmlParse.h" HXmlParse::parserWithFile("himi.xml"); ~~~ 然后Himi為了證實此解析類在Android也可以正常運行,那么這里Himi將讀出的數據展示在畫面上,iOS運行截圖如下: [![](https://box.kancloud.cn/2016-03-31_56fcd022d8f69.png "11111")](http://www.himigame.com/wp-content/uploads/2012/03/111112.png) ? [![](https://box.kancloud.cn/2016-03-31_56fcd023148d6.png "2")](http://www.himigame.com/wp-content/uploads/2012/03/24.png)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看