【原創(chuàng)】TinyJSON使用介紹
引用www.json.org上的對(duì)JSON這種數(shù)據(jù)格式的介紹:
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。 易于人閱讀和編寫。同時(shí)也易于機(jī)器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個(gè)子集。 JSON采用完全獨(dú)立于語言的文本格式,但是也使用了類似于C語言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成為理想的數(shù)據(jù)交換語言。
簡單地說,JSON就是一種基于Javascript的輕量級(jí)數(shù)據(jù)交換格式。它給我的感覺有點(diǎn)類似于xml,但寫法更隨意,并且用途不同。
這篇文章不會(huì)介紹JSON本身,因此,如果您首次接觸JSON,請(qǐng)務(wù)必先到http://www.json.org/去看完introduction.(這里還有中文版:http://www.json.org/json-zh.html)。
其實(shí)操作JSON數(shù)據(jù)比較方便的還是C#和Java,語句編寫也比較簡單、方便。C++操作JSON數(shù)據(jù)相對(duì)就要復(fù)雜一些,但只要理解了JSON這種數(shù)據(jù)格式,除了代碼字符量大一些以外,操作起來也不是很復(fù)雜。
在JSON官網(wǎng)上已經(jīng)推薦了一些使用C++操作JSON的open source項(xiàng)目,我試用了幾種,最后選擇了TinyJSON。因?yàn)樗恍枰粋€(gè).hpp文件,看起來比較輕量級(jí)。但無論是哪種,多數(shù)C++操作JSON的項(xiàng)目,都需要使用boost,所以,在正式使用TinyJSON之前,你還需要把boost編譯并配置好。我使用的是boost 1.39.0。關(guān)于boost的編譯和配置,網(wǎng)上已經(jīng)有很多介紹的文章了,這里就不再說。
說了一些廢話,下面言歸正傳,來看一下如何使用TinyJSON。
先從簡單的來,比如我們有這樣一段JSON數(shù)據(jù):
{ "login_time": 1246068720 }
一目了然,名稱是login_time,值是1246068720。用TinyJSON讀取,代碼就可以這么寫:
string strJson = "{ \"login_time\": 1246068720 }";2
grammar<char>::variant var = parse(strJson.begin(), strJson.end());3
if(var->type() == typeid(grammar<char>::object))4


{5
grammar<char>::object const& obj = boost::any_cast<grammar<char>::object>(*var);6
for(grammar<char>::object::const_iterator it = obj.begin(); it != obj.end(); ++it)7

{8
std::string strName = (*it).first;//這里你可以讀到名稱“login_time”9

10
if((*it).second->type() == typeid(int))11

{12
int nValue = boost::any_cast<int>(*(*it).second);//這里將login_time的值讀到一個(gè)整型變量里。13
}14
}15
}JSON數(shù)據(jù)基本上都是“名稱-值”這樣的格式,其中“值”有很多類型,比如上面的例子是一個(gè)整型,還有字符類型、double、布爾等等。并且“值”不限于這些,還可以是一個(gè)數(shù)組,甚至又是一段JSON數(shù)據(jù)。
下面舉個(gè)“值”是數(shù)組的例子,比如這樣的一段JSON數(shù)據(jù):
{ "auto_harvest": [26,28,25] }
相應(yīng)的讀取代碼如下:
string strJson = "{ \"auto_harvest\": [26,28,25] }";2
grammar<char>::variant var = parse(strJson.begin(), strJson.end());3
if(var->type() == typeid(grammar<char>::object))4


{5
grammar<char>::object const& obj = boost::any_cast<grammar<char>::object>(*var);6
for(grammar<char>::object::const_iterator it = obj.begin(); it != obj.end(); ++it)7

{8
std::string strName = (*it).first; //這里讀到名稱“auto_harvest”9

10
if((*it).second->type() == typeid(grammar<char>::array))11

{12
//這是一個(gè)數(shù)組類型,下面循環(huán)解析里面所有的元素13
grammar<char>::array const & a = boost::any_cast<grammar<char>::array>(*(*it).second);14
for(grammar<char>::array::const_iterator ita = a.begin(); ita != a.end(); ++ita)15

{16
if((*ita)->type() == typeid(int))17

{18
nValue = boost::any_cast<int>(*(*ita)); //這里會(huì)讀到每一個(gè)數(shù)組元素19
}20
}21
}22
}23
}再來一段“值”是另外一段JSON的例子,比如你拿到的JSON數(shù)據(jù)是這樣的:
{ "server_now": 1246117129.8, "return_code": 0, "params": {"rekoo_killer": "123456"} }
我們可以將上面的JSON數(shù)據(jù)分為“兩級(jí)”,如下:
server_now : 1246117129.8 (第一級(jí))
return_code : 0 (第一級(jí))
param : (第一級(jí))
rekoo_killer : 123456 (第二級(jí))
其中rekoo_killer : 123456是param的“值”,而rekoo_killer : 123456本身又可以單獨(dú)看做一段獨(dú)立的JSON數(shù)據(jù),它在TinyJSON中被作為一個(gè)object類型。
用TinyJSON解析上面的JSON數(shù)據(jù),代碼可以這樣寫:
string strJson = "{ \"server_now\": 1246117129.8, \"return_code\": 0, \"params\": {\"rekoo_killer\": \"123456\"} }";2
grammar<char>::variant var = parse(strJson.begin(), strJson.end());3
if(var->type() == typeid(grammar<char>::object))4


{5
grammar<char>::object const& obj = boost::any_cast<grammar<char>::object>(*var);6
for(grammar<char>::object::const_iterator it = obj.begin(); it != obj.end(); ++it)7

{8
std::string strName = (*it).first;9

10
if((*it).second->type() == typeid(int))11

{12
int nValue = boost::any_cast<int>(*(*it).second); //讀到return_code的值013
}14
else if((*it).second->type() == typeid(double))15

{16
double dValue = boost::any_cast< double >(*(*it).second); //讀到server_now的值1246117129.817
}18
else if((*it).second->type() == typeid(std::string))19

{20
std::string strValue = boost::any_cast< std::string >(*(*it).second);21
}22
else if((*it).second->type() == typeid(bool))23

{24
bool bValue = boost::any_cast< bool >(*(*it).second);25
}26
else if((*it).second->type() == typeid(grammar<char>::object))27

{28
//params的值會(huì)進(jìn)入這個(gè)判斷語句來29

30
grammar<char>::object const & o = boost::any_cast<grammar<char>::object>(*(*it).second);31
for(grammar<char>::object::const_iterator oo = o.begin(); oo != o.end(); ++oo)32

{33
std::string strName = (*oo).first; //這里讀到了名稱rekoo_killer34

35
//下面怎么做我就不寫了,rekoo_killer的值就是一個(gè)整型36
}37
}38
else if((*it).second->empty())39

{40
AfxMessageBox(_T("it's a null value"));41
}42
else43

{44
AfxMessageBox(_T("unknown type!"));45
}46
}47
}相信經(jīng)過上面的介紹,各位已經(jīng)對(duì)如何使用TinyJSON來讀取一段JSON數(shù)據(jù)有所了解了。
posted on 2009-08-05 11:56 深藍(lán)色系統(tǒng) 閱讀(5716) 評(píng)論(6) 編輯 收藏 引用 所屬分類: 皮皮片片

