引用www.json.org上的對(duì)JSON這種數(shù)據(jù)格式的介紹:
JSON(JavaScript Object Notation) 是一種輕量級(jí)的數(shù)據(jù)交換格式。 易于人閱讀和編寫(xiě)。同時(shí)也易于機(jī)器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個(gè)子集。 JSON采用完全獨(dú)立于語(yǔ)言的文本格式,但是也使用了類(lèi)似于C語(yǔ)言家族的習(xí)慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成為理想的數(shù)據(jù)交換語(yǔ)言。
簡(jiǎn)單地說(shuō),JSON就是一種基于Javascript的輕量級(jí)數(shù)據(jù)交換格式。它給我的感覺(jué)有點(diǎn)類(lèi)似于xml,但寫(xiě)法更隨意,并且用途不同。
這篇文章不會(huì)介紹JSON本身,因此,如果您首次接觸JSON,請(qǐng)務(wù)必先到http://www.json.org/去看完introduction.(這里還有中文版:http://www.json.org/json-zh.html)。
其實(shí)操作JSON數(shù)據(jù)比較方便的還是C#和Java,語(yǔ)句編寫(xiě)也比較簡(jiǎn)單、方便。C++操作JSON數(shù)據(jù)相對(duì)就要復(fù)雜一些,但只要理解了JSON這種數(shù)據(jù)格式,除了代碼字符量大一些以外,操作起來(lái)也不是很復(fù)雜。
在JSON官網(wǎng)上已經(jīng)推薦了一些使用C++操作JSON的open source項(xiàng)目,我試用了幾種,最后選擇了TinyJSON。因?yàn)樗恍枰粋€(gè).hpp文件,看起來(lái)比較輕量級(jí)。但無(wú)論是哪種,多數(shù)C++操作JSON的項(xiàng)目,都需要使用boost,所以,在正式使用TinyJSON之前,你還需要把boost編譯并配置好。我使用的是boost 1.39.0。關(guān)于boost的編譯和配置,網(wǎng)上已經(jīng)有很多介紹的文章了,這里就不再說(shuō)。
說(shuō)了一些廢話(huà),下面言歸正傳,來(lái)看一下如何使用TinyJSON。
先從簡(jiǎn)單的來(lái),比如我們有這樣一段JSON數(shù)據(jù):
{ "login_time": 1246068720 }
一目了然,名稱(chēng)是login_time,值是1246068720。用TinyJSON讀取,代碼就可以這么寫(xiě):
1
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;//這里你可以讀到名稱(chēng)“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
}
(注,需要事前定義命名空間:using namespace json;,否則你需要寫(xiě)成這樣:json::grammer<char>什么什么)JSON數(shù)據(jù)基本上都是“名稱(chēng)-值”這樣的格式,其中“值”有很多類(lèi)型,比如上面的例子是一個(gè)整型,還有字符類(lèi)型、double、布爾等等。并且“值”不限于這些,還可以是一個(gè)數(shù)組,甚至又是一段JSON數(shù)據(jù)。
下面舉個(gè)“值”是數(shù)組的例子,比如這樣的一段JSON數(shù)據(jù):
{ "auto_harvest": [26,28,25] }相應(yīng)的讀取代碼如下:
1
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; //這里讀到名稱(chēng)“auto_harvest”
9
10
if((*it).second->type() == typeid(grammar<char>::array))
11
{
12
//這是一個(gè)數(shù)組類(lèi)型,下面循環(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
}
再來(lái)一段“值”是另外一段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類(lèi)型。
用TinyJSON解析上面的JSON數(shù)據(jù),代碼可以這樣寫(xiě):
1
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的值0
13
}
14
else if((*it).second->type() == typeid(double))
15
{
16
double dValue = boost::any_cast< double >(*(*it).second); //讀到server_now的值1246117129.8
17
}
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è)判斷語(yǔ)句來(lái)
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; //這里讀到了名稱(chēng)rekoo_killer
34
35
//下面怎么做我就不寫(xiě)了,rekoo_killer的值就是一個(gè)整型
36
}
37
}
38
else if((*it).second->empty())
39
{
40
AfxMessageBox(_T("it's a null value"));
41
}
42
else
43
{
44
AfxMessageBox(_T("unknown type!"));
45
}
46
}
47
}
相信經(jīng)過(guò)上面的介紹,各位已經(jīng)對(duì)如何使用TinyJSON來(lái)讀取一段JSON數(shù)據(jù)有所了解了。