7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml


  1. 数据本地化

A CCUserDefault

系统会在默认路径cocos2d-x-2.2.3\projects\Hello\proj.win32\Debug.win32下生成一个名为UserDefault.xml.所有的key皆为char *型,value类型为bool intfloat double std::string.

读操作

bool getBoolForKey(const char* pKey);

bool getBoolForKey(const char* pKey, bool defaultValue);

 

int getIntegerForKey(const char* pKey);

int getIntegerForKey(const char* pKey, int defaultValue);

 

float getFloatForKey(const char* pKey);

float getFloatForKey(const char* pKey, float defaultValue);

 

double getDoubleForKey(const char* pKey);

double getDoubleForKey(const char* pKey, double defaultValue);

 

std::string getStringForKey(const char * pKey);

std::string getStringForKey(const char* pKey,const std::string &defaultValue);

对于没有defaultValueget方法,如果文件中没有相应的key,则得到的是0,如果有则相应的值。

对于有defaultValueget方法,如果文件中没有相应的key,则得到的是defaultValue,如果有,则返回文件中的相应的值。

B 写操作

void setBoolForKey(const char* pKey, bool value);

void setIntegerForKey(const char* pKey, int value);

void setFloatForKey(const char* pKey, float value);

void setDoubleForKey(const char* pKey, double value);

void setStringForKey(const char* pKey, const std::string & value);

Set方法有个特点,是对于相对的key后面会对前面产生覆盖效果。

C 写入文件

CCUserDefault::sharedUserDefault()->flush();

    虽然window平台是空,但是由于跨平台所导致的。

2 Xml文档格式

简介

   XML被设计用来传输和存储数据

语法

A 开头

<?xml version=”1.0” encoding=”utf-8”?>

B XML文档必须有根元素

XML文档必须有一个元素是所有其他元素的父元素。该元素称为根元素。

<root>

<child>

    <subchild>…..</subchild>

</child>

</root>

C 所有XML元素都必须有关闭标签

<p>This is a paragraph</p>

<p>This is another paragraph</p>

D XML中,XML的属性值须加引号。

<note date="08/08/2008">

<to>George</to>

<from>John</from>

</note>

E XML中的注释

<!— This is a comment -->

XML元素

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

元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。

<bookstore>

<book category="CHILDREN">

<title>Harry Potter</title>

<author>J K. Rowling</author>

<year>2005</year>

<price>29.99</price>

</book>

<book category="WEB">

<title>Learning XML</title>

<author>Erik T. Ray</author>

<year>2003</year>

<price>39.95</price>

</book>

</bookstore>

例:

<?xml version="1.0" encoding="ISO-8859-1"?>

<note>

<to>George</to>

<from>John</from>

<heading>Reminder</heading>

<body>Don't forget the meeting!</body>

</note>

F: 生成xml文档

头文件

#include "support/tinyxml2/tinyxml2.h"

using namespace tinyxml2;

 

void makeXML(const char * fileName)

{

std::string filePath =

CCFileUtils::sharedFileUtils()->getWritablePath() + fileName;

tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();

 

//xml 声明(参数可选)

XMLDeclaration *pDel = pDoc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");

pDoc->LinkEndChild(pDel);

 

//添加plist 节点

XMLElement *plistElement = pDoc->NewElement("plist");

plistElement->SetAttribute("version", "1.0");

pDoc->LinkEndChild(plistElement);

XMLComment *commentElement = pDoc->NewComment("this is xml comment");

plistElement->LinkEndChild(commentElement);

 

//添加dic 节点

XMLElement *dicElement = pDoc->NewElement("dic");

plistElement->LinkEndChild(dicElement);

 

//添加key 节点

XMLElement *keyElement = pDoc->NewElement("key");

keyElement->LinkEndChild(pDoc->NewText("Text"));

dicElement->LinkEndChild(keyElement);

XMLElement *arrayElement = pDoc->NewElement("array");

dicElement->LinkEndChild(arrayElement);

for (int i = 0; i < 3; i++) {

XMLElement *elm = pDoc->NewElement("name");

elm->LinkEndChild(pDoc->NewText("Cocos2d-x"));

arrayElement->LinkEndChild(elm);

}

pDoc->SaveFile(filePath.c_str());

pDoc->Print();

delete pDoc;

}

cocos2d-x-2.2.3\projects\Hello\proj.win32\Debug.win32

<?xml version="1.0" encoding="UTF-8"?>

<plist version="1.0">

<!--this is xml comment-->

<dic>

<key>Text</key>

<array>

<name>Cocos2d-x</name>

<name>Cocos2d-x</name>

<name>Cocos2d-x</name>

</array>

</dic>

</plist>

17.3.4解析xml

void parseXML(const char * fileName) {

std::string filePath = CCFileUtils::sharedFileUtils()->getWritablePath() + fileName;

tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();

XMLError errorId = pDoc->LoadFile(filePath.c_str());

 

if (errorId != 0) {

//xml 格式错误

return;

}

 

XMLElement *rootEle = pDoc->RootElement();

//获取第一个节点属性

const XMLAttribute *attribute = rootEle->FirstAttribute();

//打印节点属性名和值

CCLog("attribute_name = %s,attribute_value = %s", attribute->Name(),

attribute->Value());

XMLElement *dicEle = rootEle->FirstChildElement("dic");

XMLElement *keyEle = dicEle->FirstChildElement("key");

   

if (keyEle) {

CCLog("keyEle Text= %s", keyEle->GetText());

}

 

XMLElement *arrayEle = keyEle->NextSiblingElement();

XMLElement *childEle = arrayEle->FirstChildElement();

 

while (childEle) {

CCLog("childEle Text= %s", childEle->GetText());

childEle = childEle->NextSiblingElement();

}

 

delete pDoc;

}

attribute_name = version,attribute_value = 1.0

keyEle Text= Text

childEle Text= Cocos2d-x

childEle Text= Cocos2d-x

childEle Text= Cocos2d-x

UserDefault.Xml操作案例:

T22UserDefault.h

#ifndef __T22CCUserDefault_H__

#define __T22CCUserDefault_H__

#include "cocos2d.h"

#include "TBack.h"

 

class T22CCUserDefault :public TBack

{

public:

    CREATE_FUNC(T22CCUserDefault);

    bool init();

    static CCScene * scene();

 

    void makeXML(char * fileName);

    void parseXML(char * fileName);

};

 

#endif

T22UserDefault.cpp

#include "T22UserDefault.h"

#include "AppMacros.h"

#include "support/tinyxml2/tinyxml2.h"

 

using namespace tinyxml2;

 

CCScene * T22CCUserDefault::scene()

{

    CCScene * scene = CCScene::create();

    T22CCUserDefault * layer = T22CCUserDefault::create();

    scene->addChild(layer);

    return scene;

}

 

bool T22CCUserDefault::init()

{

    TBack::init();

    //通过这种方式向UserDefault.xml中写内容

    CCUserDefault::sharedUserDefault()->setIntegerForKey("integer", 100);

    CCUserDefault::sharedUserDefault()->setStringForKey("string","oooo");

    //获得xml的路径

    std::string str = CCUserDefault::sharedUserDefault()->getXMLFilePath();

    //打印xml的路径

    CCLog("path = %s", str.c_str());

 

    CCLog("isXMLExist = %d", CCUserDefault::sharedUserDefault()->isXMLFileExist());

 

    CCUserDefault::sharedUserDefault()->flush();

    //如果有这个key的值则打印出,如果没有这个key则返回默认的值120

    int value = CCUserDefault::sharedUserDefault()->getIntegerForKey("integer", 120);

    CCLog("value = %d", value);

 

    return true;

}

运行结果:

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

UserDefault.xml的内容:

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

操作xml和解释xml

#include "T22UserDefault.h"

#include "AppMacros.h"

#include "support/tinyxml2/tinyxml2.h"

 

using namespace tinyxml2;

 

CCScene * T22CCUserDefault::scene()

{

    CCScene * scene = CCScene::create();

    T22CCUserDefault * layer = T22CCUserDefault::create();

    scene->addChild(layer);

    return scene;

}

 

bool T22CCUserDefault::init()

{

    TBack::init();

 

    makeXML("test");

    parseXML("test");

 

    return true;

}

 

void T22CCUserDefault::makeXML(char * fileName) {

    std::string filePath =

        CCFileUtils::sharedFileUtils()->getWritablePath() + fileName;

 

    tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();

    //xml 声明(参数可选)

    XMLDeclaration *pDel = pDoc->NewDeclaration("xml version=\"1.0\" encoding = \"UTF-8\"");

    pDoc->LinkEndChild(pDel);

    //添加 plist 节点

    XMLElement *plistElement = pDoc->NewElement("plist");

    plistElement->SetAttribute("version", "1.0");

    pDoc->LinkEndChild(plistElement);

 

 

    XMLComment *commentElement = pDoc->NewComment("this is x comment");

    plistElement->LinkEndChild(commentElement);

    //添加 dic 节点

    XMLElement *dicElement = pDoc->NewElement("dic");

    plistElement->LinkEndChild(dicElement);

    //添加 key 节点

    XMLElement *keyElement = pDoc->NewElement("key");

    keyElement->LinkEndChild(pDoc->NewText("Text"));

    dicElement->LinkEndChild(keyElement);

 

    XMLElement *arrayElement = pDoc->NewElement("array");

    dicElement->LinkEndChild(arrayElement);

    for (int i = 0; i < 3; i++) {

        XMLElement *elm = pDoc->NewElement("name");

        elm->LinkEndChild(pDoc->NewText("Cocos2d-x"));

        arrayElement->LinkEndChild(elm);

    }

    pDoc->SaveFile(filePath.c_str());

    pDoc->Print();

    delete pDoc;

}

 

void T22CCUserDefault::parseXML(char * fileName)

{

    std::string filePath =

        CCFileUtils::sharedFileUtils()->getWritablePath() + fileName;

    tinyxml2::XMLDocument *pDoc = new tinyxml2::XMLDocument();

    XMLError errorId = pDoc->LoadFile(filePath.c_str());

    if (errorId != 0) {

        //xml 格式错误

        return;

    }

    XMLElement *rootEle = pDoc->RootElement();

    //获取第一个节点属性

    const XMLAttribute *attribute = rootEle->FirstAttribute();

    //打印节点属性名和值

    CCLog("attribute_name = %s,attribute_value = %s", attribute->Name(), attribute->Value());

 

    XMLElement *dicEle = rootEle->FirstChildElement("dic");

    XMLElement *keyEle = dicEle->FirstChildElement("key");

    if (keyEle) {

        CCLog("keyEle Text= %s", keyEle->GetText());

    }

    XMLElement *arrayEle = keyEle->NextSiblingElement();

    XMLElement *childEle = arrayEle->FirstChildElement();

    while (childEle) {

        CCLog("childEle Text= %s", childEle->GetText());

        childEle = childEle->NextSiblingElement();

    }

    delete pDoc;

}

运行结果:

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

Xml文件:

 

 

 

CCString,CCArray,CCDictionary

init()方法中

 

CCString *str = CCString::create("1234");

CCLog("CCString str = %s", str->getCString());

CCLog("CCString intTypeValue = %d", str->intValue());

运行结果:

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

数据结构:CCString

/*使用std::string 创建了一个字符串, 你也可以传递一个c 字符串指针,因为

std::string 的构造函数可以访问c 字符串指针

* @返回的CCString 指针是一个自动释放对象,

*也就意味着你不需要调用release 操作,除非你retain .

*/

static CCString* create(const std::string& str);

/*使用格式化方式来创建一个字符串,这个方法和c 语言里面的‘sprintf’类似,默认

缓存大小是(1024*100bytes

*假如你想要改变这个缓存大小,你可以去CCString.cpp 中,更改kMaxStringLen

这个宏定义。

* @返回的CCString 指针是一个自动释放对象,

*也就意味着你不需要调用release 操作,除非你retain .

*/

static CCString* createWithFormat(const char* format, …);

/* 使用二进制数据来创建字符串

* @返回的CCString 指针是一个自动释放对象,

*也就意味着你不需要调用release 操作,除非你retain .

*/

static CCString* createWithData(const unsigned char* pData, unsigned

long nLen);

/*使用一个文件来创建一个字符串,

* @return A CCString pointer which is an autorelease object pointer,

* it means that you needn't do a release operation unless you retain

it.

*/

static CCString* createWithContentsOfFile(const char* pszFileName);

转换

CCString 允许CCString 实例变量转换为另外类型的变量。

/* convert to int value */

int intValue() const;

/* convert to unsigned int value */

unsigned int uintValue() const;

/* convert to float value */

float floatValue() const;

/* convert to double value */

double doubleValue() const;

/* convert to bool value */

bool boolValue() const;

常见的宏定义

#define CCStringMake(str) CCString::create(str)

#define ccs CCStringMake

CCArray

CCArray是一个面向对象包装类

CCArray继承至CCObjectCCObject主要是为了自动内存管理而创建的)并且提供了一系列接口。

 

创建

/** 创建一个数组*/

static CCArray* create();

/** 使用一些对象创建数组*/

static CCArray* create(CCObject* pObject, …);

/** 使用一个对象创建数组*/

static CCArray* createWithObject(CCObject* pObject);

/** 创建一个指定大小的数组*/

static CCArray* createWithCapacity(unsigned int capacity);

/** 使用一个现有的CCArray 数组来新建一个数组*/

static CCArray* createWithArray(CCArray* otherArray);

插入

/** 插入一个对象*/

void addObject(CCObject* object);

/** 插入别外一个数组里面的全部对象*/

void addObjectsFromArray(CCArray* otherArray);

/** 在一个确定的索引位置插入一个对象*/

void insertObject(CCObject* object, unsigned int index);

删除

/** 移除最后的一个对象*/

void removeLastObject(bool bReleaseObj = true);

/**移除一个确定的对象*/

void removeObject(CCObject* object, bool bReleaseObj = true);

/** 移除一个确定索引位置的元素*/

void removeObjectAtIndex(unsigned int index, bool bReleaseObj = true);

/** 移除全部元素*/

void removeObjectsInArray(CCArray* otherArray);

/** 移除所有对象*/

void removeAllObjects();

/** 快速移除一个对象*/

void fastRemoveObject(CCObject* object);

/** 快速移除一个确定索引位置的对象*/

void fastRemoveObjectAtIndex(unsigned int index);

 

remove fastRemove 有什么区别,可以看看源代码,remove 是从CCArray中完全的移除,fastRemove 只是将CCArray 中对应的对象释放掉了,没够改变整个CCArray 的结构。从代码上来看,区别在于删除元素之后,是否把数组之后的元素向前移动覆盖掉之前位置的元素。代码上的差别如下所示:

unsigned int remaining = arr->num - index;

if(remaining>0)

{

memmove((void *)&arr->arr[index], (void *)&arr->arr[index+1],

remaining * sizeof(CCObject*));

}

遍历

CCARRAY_FOREACH(arr, obj)

主要事项

CCArray 一般不会被增加到其他类中,所以他的引用计数是1,并且设置为autorelease 对象。创建CCArray 对象并且retain,然后在这个类中的析构函数中调用release 方法来释放内存。

如果CCObject 对象添加到CCArray 中,那么CCObject 对象的引用计数将

会加1.

 

CCDictionary

CCDirtionary使用UTHash实现的

关键字类型

CCDictionary支持两种类型的关键字,一个是std::string,一个是int.一个CCDictionary实例对象只支持唯一的关键字。所以在你调用”setObject”方法的时候,你需要确认一下。

 

创建

static CCDictionary * create();

static CCDictionary * createWithDictionary(CCDictionary *srcDict)

static CCDictionary * createWithContentsOffFile(const char * pFileName);

 

插入

相同keyvalue会发生覆盖行为。

void setObject(CCObject *pObject,const std::string &key);

void setObject(CCObject *pObject,intptr_t key);

 

删除

void removeObjectForKey (const std::string &key)

void removeObjectForKey (intptr_t key)

void removeObjectsForKeys (CCArray *pKeyArray)

void removeObjectForElememt (CCDictElement *pElement)

void removeAllObjects ()

 

遍历

实现了CCDICT_FOREACH 方法来遍历整个字典。而且使用CCDICT_FOREACH 的方式和使用CCARRAY_FOREACH 的方式非常类似

CCDictElement* pElement = NULL;

CCDICT_FOREACH(theDict, pElement)

{

CCObjectSubClass* pSubClassObj = (CCObjectSubClass*)pElement->getObject();

// 你也可以得到当前key,但是你需要确定key 的类型。

std::string oneStrKey = pElement->getStrKey(); // 假如key 的类型是string

// int oneIntKey = pElement->getIntKey(); // 假如有key 的类型是integer

// 下面就可以使用上面pSubClassObj 对象做一些操作了

}

举例

// Create a dictionary, return an autorelease object.

CCDictionary* pDict = CCDictionary::create();

// Insert objects to dictionary

CCString* pValue1 = CCString::create("100");

CCString* pValue2 = CCString::create("120");

CCInteger* pValue3 = CCInteger::create(200);

pDict->setObject(pValue1, "key1");

pDict->setObject(pValue2, "key2");

pDict->setObject(pValue3, "key3");

// Get the object for key

CCString* pStr1 = (CCString*)pDict->objectForKey("key1");

CCLog("{ key1: %s }", pStr1->getCString());

CCInteger* pInteger = (CCInteger*)pDict->objectForKey("key3");

CCLog("{ key3: %d }", pInteger->getValue());

结合xml支持中文

CCDictionary * dic = CCDictionary::createWithContentsOfFile("chinese.xml");

CCString * str = (CCString *)dic->objectForKey("people1");

CCLabelTTF * ttf = CCLabelTTF::create(str->getCString(), "Arial",20);

ttf->setPosition(ccp(240, 160));

addChild(ttf);

return true;

 

案例:

bool T22CCUserDefault::init()

{

    TBack::init();

   

    CCDictionary * dic = CCDictionary::create();

    dic->retain();

 

    CCString *value1 = CCString::create("100");

    CCString *value2 = CCString::create("200");

 

    //第一个是value,第二个是key的意思

    dic->setObject(value1, "key1");

    dic->setObject(value2, "key2");

 

    CCString * str2 = (CCString *)dic->objectForKey("key1");

    //运行结果100

    CCLog("%d", str2->intValue());

 

    CCLabelTTF * ttf = CCLabelTTF::create(str2->getCString(), "Courier New", 30);

    ttf->setPosition(ccp(240,160));

    addChild(ttf);

 

    return true;

}

运行结果:

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

 

上一篇:PostgreSQL 11 新特性解读:支持并行哈希连接(Parallel Hash Joins)"


下一篇:30分钟 Python 教程