Bookmark and Share

Lee's 程序人生

HTML CSS Javascript XML AJAX ATLAS C# C++ 数据结构 软件工程 设计模式 asp.net Java 数字图象处理 Sql 数据库
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

转:TinyJSON使用介绍

Posted on 2009-10-14 21:02  analyzer  阅读(1408)  评论(0)    收藏  举报

引用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读取,代码就可以这么写:

 1string strJson = "{ \"login_time\": 1246068720 }";
 2grammar<char>::variant var = parse(strJson.begin(), strJson.end());
 3if(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}
(注,需要事前定义命名空间:using namespace json;,否则你需要写成这样:json::grammer<char>什么什么)

JSON数据基本上都是“名称-值”这样的格式,其中“值”有很多类型,比如上面的例子是一个整型,还有字符类型、double、布尔等等。并且“值”不限于这些,还可以是一个数组,甚至又是一段JSON数据。

下面举个“值”是数组的例子,比如这样的一段JSON数据:
{ "auto_harvest": [26,28,25] }
相应的读取代码如下:
 1string strJson = "{ \"auto_harvest\": [26,28,25] }";
 2grammar<char>::variant var = parse(strJson.begin(), strJson.end());
 3if(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数据,代码可以这样写:

 1string strJson = "{ \"server_now\": 1246117129.8, \"return_code\": 0, \"params\": {\"rekoo_killer\": \"123456\"} }";
 2grammar<char>::variant var = parse(strJson.begin(), strJson.end());
 3if(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的值会进入这个判断语句来
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_killer
34
35                //下面怎么做我就不写了,rekoo_killer的值就是一个整型
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}

相信经过上面的介绍,各位已经对如何使用TinyJSON来读取一段JSON数据有所了解了。

FROM:http://www.cppblog.com/epubcn/archive/2009/08/05/92267.html