【原創】TinyJSON使用介紹
引用www.json.org上的對JSON這種數據格式的介紹:
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 易于人閱讀和編寫。同時也易于機器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一個子集。 JSON采用完全獨立于語言的文本格式,但是也使用了類似于C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成為理想的數據交換語言。
簡單地說,JSON就是一種基于Javascript的輕量級數據交換格式。它給我的感覺有點類似于xml,但寫法更隨意,并且用途不同。
這篇文章不會介紹JSON本身,因此,如果您首次接觸JSON,請務必先到http://www.json.org/去看完introduction.(這里還有中文版:http://www.json.org/json-zh.html)。
其實操作JSON數據比較方便的還是C#和Java,語句編寫也比較簡單、方便。C++操作JSON數據相對就要復雜一些,但只要理解了JSON這種數據格式,除了代碼字符量大一些以外,操作起來也不是很復雜。
在JSON官網上已經推薦了一些使用C++操作JSON的open source項目,我試用了幾種,最后選擇了TinyJSON。因為它只需要一個.hpp文件,看起來比較輕量級。但無論是哪種,多數C++操作JSON的項目,都需要使用boost,所以,在正式使用TinyJSON之前,你還需要把boost編譯并配置好。我使用的是boost 1.39.0。關于boost的編譯和配置,網上已經有很多介紹的文章了,這里就不再說。
說了一些廢話,下面言歸正傳,來看一下如何使用TinyJSON。
先從簡單的來,比如我們有這樣一段JSON數據:
{ "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的值讀到一個整型變量里。13
}14
}15
}JSON數據基本上都是“名稱-值”這樣的格式,其中“值”有很多類型,比如上面的例子是一個整型,還有字符類型、double、布爾等等。并且“值”不限于這些,還可以是一個數組,甚至又是一段JSON數據。
下面舉個“值”是數組的例子,比如這樣的一段JSON數據:
{ "auto_harvest": [26,28,25] }
相應的讀取代碼如下:
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
//這是一個數組類型,下面循環解析里面所有的元素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)); //這里會讀到每一個數組元素19
}20
}21
}22
}23
}再來一段“值”是另外一段JSON的例子,比如你拿到的JSON數據是這樣的:
{ "server_now": 1246117129.8, "return_code": 0, "params": {"rekoo_killer": "123456"} }
我們可以將上面的JSON數據分為“兩級”,如下:
server_now : 1246117129.8 (第一級)
return_code : 0 (第一級)
param : (第一級)
rekoo_killer : 123456 (第二級)
其中rekoo_killer : 123456是param的“值”,而rekoo_killer : 123456本身又可以單獨看做一段獨立的JSON數據,它在TinyJSON中被作為一個object類型。
用TinyJSON解析上面的JSON數據,代碼可以這樣寫:
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的值會進入這個判斷語句來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的值就是一個整型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
}相信經過上面的介紹,各位已經對如何使用TinyJSON來讀取一段JSON數據有所了解了。
posted on 2009-08-05 11:56 深藍色系統 閱讀(5717) 評論(6) 編輯 收藏 引用 所屬分類: 皮皮片片

