LoginSignup
2
2

More than 5 years have passed since last update.

【cocos2d-x】tinyxml2によるローカルXMLファイルの読み込み

Last updated at Posted at 2017-02-06

cocos2d-xでasset内のXMLを読み込んでパースしてみました。
開発環境はAndroidStudio2.2.3、cocos2d-xはver.3.11、動かした実機はXperiaVL SOL21、AndroidのOSバージョンは4.1です。

XMLパースは「tinyxml2」を使いました。
cocos2d-xではヘッダファイルを読み込めばそれだけで使えるいい子です。
(githubなどで持ってくるのも手です)
ライセンスはzlibライセンスです。(詳細はググってくださいねー)

test.xml(読み込むXMLファイル)

<charadata>
    <item>
    <id>0</id>
    <reach>0.0</reach>
    <power>8</power>
    <target>0</target>
    </item>

    <item>
    <id>1</id>
    <reach>0.0</reach>
    <power>8</power>
    <target>0</target>
    </item>

    <item>
    <id>2</id>
    <reach>0.0</reach>
    <power>8</power>
    <target>2</target>
    </item>

……(略)
</charadata>

cocos2d-x内、cppファイル。

XML読み込み、パース、表示。

#include "tinyxml2/tinyxml2.h"

//using namespace tinyxml2;<-わかりやすくするためネームスペースはコメントアウト

//以下はどっか適当な場所で〜
//ファイルパスの取得
FileUtils* fileUtils = FileUtils::getInstance();
const char* path = "test.xml";
std::string fullpath = fileUtils->fullPathForFilename(path);
log("filepath:%s",fullpath.c_str());

//XMLを読み込んでパース
auto content = fileUtils->getDataFromFile(fullpath.c_str());
tinyxml2::XMLDocument *doc = new XMLDocument();
auto ret = doc->Parse((const char*)content.getBytes(), content.getSize());
if (ret != tinyxml2::XML_NO_ERROR) {
    log("xml:fail:%d",ret);
    return;
}

//XMLのルートを呼び出す
auto rootElement = doc->RootElement();
if (!rootElement){
    log("xml:rootElement Error");
    return;
}

//最初の要素を呼ぶ
tinyxml2::XMLElement* childElement = rootElement->FirstChildElement("item");

while (childElement) {
    tinyxml2::XMLElement* element_id = childElement->FirstChildElement("id");
    log("id:%s",element_id->GetText());
    tinyxml2::XMLElement* element_reach = childElement->FirstChildElement("reach");
    log("reach:%s",element_reach->GetText());
    tinyxml2::XMLElement* element_power = childElement->FirstChildElement("power");
    log("power:%s",element_power->GetText());
    tinyxml2::XMLElement* element_target = childElement->FirstChildElement("target");
    log("target:%s",element_target->GetText());
    //次の要素を呼ぶ
    childElement = childElement->NextSiblingElement("item");
}

/*
//こっちの方がスマートかも?(僕はこっち使ってます)
for(tinyxml2::XMLElement* childElement= rootElement->FirstChildElement("item");childElement!= 0; childElement= childElement->NextSiblingElement("item") ) {
    tinyxml2::XMLElement* element_id = childElement->FirstChildElement("id");
    log("id:%s",element_id->GetText());
    tinyxml2::XMLElement* element_reach = childElement->FirstChildElement("reach");
    log("reach:%s",element_reach->GetText());
    tinyxml2::XMLElement* element_power = childElement->FirstChildElement("power");
    log("power:%s",element_power->GetText());
    tinyxml2::XMLElement* element_target = childElement->FirstChildElement("target");
    log("target:%s",element_target->GetText());
}
*/

-プログラム実行、XML内容表示

01-20 01:43:40.148: D/cocos2d-x debug info(18446): id:0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): reach:0.0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): power:8
01-20 01:43:40.148: D/cocos2d-x debug info(18446): target:0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): id:1
01-20 01:43:40.148: D/cocos2d-x debug info(18446): reach:0.0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): power:8
01-20 01:43:40.148: D/cocos2d-x debug info(18446): target:0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): id:2
01-20 01:43:40.148: D/cocos2d-x debug info(18446): reach:0.0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): power:8
01-20 01:43:40.148: D/cocos2d-x debug info(18446): target:2
01-20 01:43:40.148: D/cocos2d-x debug info(18446): id:3
01-20 01:43:40.148: D/cocos2d-x debug info(18446): reach:0.0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): power:8
01-20 01:43:40.148: D/cocos2d-x debug info(18446): target:2
01-20 01:43:40.148: D/cocos2d-x debug info(18446): id:4
01-20 01:43:40.148: D/cocos2d-x debug info(18446): reach:0.0
01-20 01:43:40.148: D/cocos2d-x debug info(18446): power:8
01-20 01:43:40.148: D/cocos2d-x debug info(18446): target:2

……

こんな感じでできました。

tinyxml2::XMLDocument::LoadFileについて

ちなみに最初はFileUtils::getDataFromFileを使わないでtinyxml2::XMLDocument::LoadFileを使ってみたのですが、正常に動けば0を返すところが、Androidでは3を返してちゃんと動作しませんでした。

const char* path = "test.xml";
std::string fullpath = fileUtils->fullPathForFilename(path);
tinyxml2::XMLDocument *doc = new XMLDocument();
auto ret= doc ->LoadFile(fullpath.c_str());
if (ret != tinyxml2::XML_NO_ERROR) {
    //xml
    log("xml:fail:%d",ret);
    return;
}

この3が何を意味するのか詳しく調べないとわからないのですが、できればLoadFileメソッドを使いたかったなーと。
こちらのほうがコードを簡素に書けるので。
iPhoneだとどうなんだろうか?

【追記】
tinyxml2のcppとhのソースを見たら、「ファイルが見つからない」ということを指すみたいですね〜。
次組むときはもうちょっと追ってみます。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2