複製鏈接
請複製以下鏈接發送給好友

數據解析

鎖定
網絡通信過程中需要傳輸數據,常用的數據格式有兩種:JSON、XML。Cocos2d-x對JSON和XML這兩種數據格式的解析提供了支持,主要為:JOSN數據解析、XML數據解析。JOSN數據解析的過程為:首先創建JSON文件,然後在類中包含document.h和cocos-ext.h頭文件,接着通過FileUtils獲得JSON文件路徑,並通過Document對象解析JSON數據,最終獲得不同類型的數據值。XML數據解析的過程為:首先創建XML文件,接着在類中包含頭文件並使用命名文件,然後獲得XML文件全路徑,並加載XML文件,最後獲得元素並解析。
中文名
數據解析
外文名
Data analysis
平台基礎
Cocos2d-x
兩種解析
JOSN數據解析、XML數據解析
解析庫
TinyXML
應用領域
Cocos2d-x3.x遊戲開發

數據解析基本情況

Cocos2d-x可以開發遊戲,它提供了多種網絡連接方式,即時通信Socket、WebSocket、基於http的HttpCline、curl等等。在網絡通信過程中,需要傳輸數據,常用的數據格式有兩種,一種是JSON,另外一種是XML,Cocos2d-x對這些數據格式的解析提供了支持,主要為:JOSN數據解析、XML數據解析。
JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。它使得人們可以很容易地進行閲讀和編寫,同時也方便了機器進行解析和生成。JSON採用完全獨立於程序語言的文本格式,但是也使用了類C語言的習慣(包括C、C++、C#、Java、JavaScript、Perl和Python等),這些特性使得JSON成為理想的數據交換語言。 [1] 
TinyXML是一個開源的解析XML的解析庫,Cocos2d-x集成了該庫,在Cocos2d-x項目的根目錄的extemal/tinyxml2目錄下面有該類的實現。TinyXML解析庫通過解析XML文件,在內存中生成DOM模型,從而使我們可以很方便地遍歷這棵XML樹。 [1] 

數據解析JSON數據解析

在Cocos2d.x根目錄的external/json目錄下面,是JSON處理的相關類,這裏主要使用document.h這個頭文件,該文件中的兩個核心是GenericValue和GenericDocument,GenericDocument繼承GeneficValue。使用GenericDocument用來處理文檔內容,如解析文檔內容;而GenericValue主要處理值內容,即文檔內部的key-value鍵值對內容,可以根據key獲得value。GenericValue和GenericDocument都被重新進行了類型定義。所以可以使用類型定義後的名稱。 [1] 
typedef GenericDocument
typedef GenericValue
Value重載了數組下標操作符[],所以我們可以使用該操作符,根據JSON文件中的key獲得value。
const GenericValue & operator [] (const Ch* name) const{
const_cast(*this)[name];}
Value還提供了一組GetXXX方法,根據不同的數據類型,獲得相應的值。
通過一個實例來演示如何解析JSON數據,操作步驟如下: [1] 
創建JSON文件
在項目的classes文件夾下創建一個JSON文件,內容如下:
{"pets":["dog","cat"],"stuInfo":{

"stuAge":23,"stuName":"rose","birthday":"1990-01-12"},"username","tom","other":[true,30]}
在該文件中,pets是一個數組,表示寵物,有兩個值dog和pet;stuInfo是一個學生信息;後面是一個usename;最後還有一個other數組。 [1] 
在類中包含document.h和cocos-ext.h頭文件
#include "cocos-ext.h"

#include "json/document.h"
通過FileUtils獲得JSON文件路徑
const char* file_path = FileUtils::getInstance()->fullPathForFilename("hello.json").c_str();
log("文件路徑path=%s",file_path);
通過Document對象解析JOSN數據
//文檔對象
rapidjson::Document dl;
//獲得JSON字符串內容
std::string contentStr = FileUtils::getInstance()->getStringFromFile(file_path);
//解析
dl.Parse<0>(contentStr.c_str());
//輸出JSON文件的內容
printf("%s\n",contentStr.c_str());
獲得不同類型的數據值
通過數組下標操作符[],根據key獲得Value,並使用Value的GetXXX方法獲得不同類型的數據值。 [1] 
//獲取JSON中數組的方法(寵物數組)[dog,cat]
const rapidjson::Value & v=d1["pets"];
for(unsigned int i=0;i<v.Size();++i){
const rapidjson::Value & val=v[i];
log("%s",val.GetString());
}
//根據key獲得value(學生信息)"stuInfo":{"stuAge":23,"stuName":"rose","birthday":"1990-01-12"}
const rapidjson::Value & v2=d1["stuInfo"];
//獲得整型值
const rapidjson::Value&val1 = v2["stuAge"];
log("val.GetString()=%d",vall.GetInt());
//獲得字符串值
const rapidjson::Value&val2 = v2["stuName"];
log("val.GetString()=%s",val2.GetString());
//獲得字符串值
const rapidjson::Value&val3 = v2["birthday"];
log("val.GetString()=%s",val3.GetString());
//根據key獲得value(other)"other":[true,30]
const rapidjson::Value&v3=d1["other"];
for(unsigned int i=0;i<v3.Size();++i){
    const rapidjson::Value&val=v3[i];
    if(val.IsBool()){
    log("%d",val.GetBool());
    }
    if(val.IsInt()){
    log("%d",val.GetInt());
    } 
}

數據解析XML數據解析

在TinyXML中,根據XML的各種元素定義了一些類。
(1)class XMLDocument:文檔;
(2)class XMLElement:元素;
(3)class XMLAttribute:屬性;
(4)class XMLComment:註釋;
(5)class XMLNode:節點;
(6)class XMLText:文本;
(7)class XMLDeclaration:聲明;
(8)class XMLUnknown:未知部分。 [1] 
一個解析XML文件的實例的具體操作步驟如下:
創建XML文件
在項目的Classes目錄下面創建一個XML文件,文件內容如下;
<?xml version="1.0" encoding=”UTF8”?>
<student 1ist>
    <student>
       <stu_num>2014100101</stu_num>
       <stu_name>tom</stu_name>
       <stu_class>C01</stu_class>
    </student>
    <studant>
       <stu_num>2014100102</stu_num>
       <stu_name>kite</stu_name>
       <stu_class>C02</stu_class>
    </student>
    <student>
       <stu_num>2014100103</stu_num>
       <stu_name>rose</stu_name>
       <stu_class>C02</stu_class>
    </student>
</student_list>
上述文件中有三個學生信息,每一個學生信息中又有學號(stu_num)、姓名(stu_name)、班級(stu_class)三個元素。 [1] 
在類中包含頭文件並使用命名空間
#include "cocos-ext.h"
#include "tinyxml2/tinyxml2.h"
using namespace tinyxml2;
獲得XML文件全路徑
//獲得外部文件路徑
const char*file_path = FileUtils::getInstance()->fullPathFoeFilename("test.xml").c_str();
//打印輸出
log("external file path = %s",file_path)
創建文件檔,並加載XML文件
//創建XMLDocument
XMLDocument* myDocument = new tinyxml2::XMLDocument();
//加載文件
myDocument->LoadFile(file_path);
獲得元素並解析
獲得XML文件的根元素及其子元素和兄弟元素,並進行解析,具體如下: [1] 
//獲得根元素
tinyxml2::XMLElement* rootElement = myDocument->RootElement();
//第一個子元素
XMLElement* studentElement = rootElement->FirshChildElement();
//如果studentElement不為空一直循環
while(studentElement){
    //studentElement的第一個子元素
    XMLElement* element = studentElement->FirshChildElement();
    while(element){
    //獲得元素內容
    log("信息:%s",element->GetText());
    //下一個兄弟元素
    element = element->NextSiblingElement();
    }
    //下一個兄弟元素
    studentElement = studentElement->NextSiblingElement();
}
參考資料
  • 1.    郭宏志編著.Cocos2d-x3.x遊戲開發詳解.北京:電子工業出版社,2015:192-196