一、在客户端读写 JSON

在本章中,我们将涵盖以下食谱:

  • 用 JavaScript 读写 JSON
  • 用 c++读写 JSON
  • 用 c#读写 JSON
  • 用 Java 读写 JSON
  • 在 Perl 中读写 JSON
  • 在 Python 中读写 JSON

除了用 Python 读和写 JSON 之外,我们将首先向您展示 JSON 格式的简要回顾,以帮助为本书后面的内容奠定基础。

简介

JSON代表JavaScript Object Notation。 它是一种将数据表示为带有值的属性的开放标准。 最初来源于 JavaScript 语法(因此得名)用于 web 应用的一种替代更详细的和结构化可扩展标记语言(XML【显示】),现在是用于数据序列化和传输在许多独立和 web 应用。****

**JSON 提供了在客户机和服务器之间封装数据的理想方法。 在第一章中,您将学习如何在本章开始时指定的语言中使用 JSON。

这些语言通常用于客户端开发,这是我们在这里重点讨论的。 我们将在第二章中更多地了解服务器端语言。

让我们看看一些 JSON 返回的 web API,可以在 http://www.aprs.fi,修改一点,我明确的例子(之后,在第四章,使用 JSON 与 jQuery 和 AngularJS在 AJAX 应用中,您将了解如何获取这些数据你自己使用 web 浏览器和 JavaScript):

{
  "command":"get",
  "result":"ok",
  "what":"loc",
  "found":2,
  "entries":[
    {
      "class":"a",
      "name":"KF6GPE",
      "type":"l",
      "time":"1399371514",
      "lasttime":"1418597513",
      "lat":37.17667,
      "lng":-122.14650,
      "symbol":"\/-",
      "srccall":"KF6GPE",
    },
    {
      "class":"a",
      "name":"KF6GPE-7",
      "type":"l",
      "time":"1418591475",
      "lasttime":"1418591475",
      "lat":37.17633,
      "lng":-122.14583,
      "symbol":"\\K",
      "srccall":"KF6GPE-7",
    }
  ]
}

提示

下载示例代码

您可以从您的帐户http://www.packtpub.com下载您所购买的所有 Packt Publishing 书籍的示例代码文件。 如果您在其他地方购买了这本书,您可以访问http://www.packtpub.com/support并注册,直接将文件通过电子邮件发送给您。

关于这个例子,有几点需要注意:

  • 数据被组织成属性和值,每个属性和值由冒号分隔。 (请注意,JSON 文档也可以是单个值,如字符串、浮点数、整数或布尔值。)
  • 属性显示为由冒号左侧的双引号括起来的字符串。
  • 值在冒号的右侧,可以是以下内容:
    • 字符串(用双引号括起来),如KF6GPE
    • 数字(整数或浮点数),如237.17667
    • 数组(方括号中以逗号分隔的值),例如entries的值
    • 由更多属性和值组成的整个对象,例如entries值中的两个数组值
    • 或者(虽然这个例子没有显示它),布尔值truefalse
  • 请注意,JSON 不支持许多其他类型的值,例如日期/时间对或单个字符。
  • 尽管从这个示例中还不完全清楚,但空白是无关紧要的。 例如,不需要每对都在该行中,而且缩进是完全任意的。

JSON 的 attribute-name-attribute-value 属性,以及嵌套值和表示数组的能力,为 JSON 提供了很大的灵活性。 你可以代表很多共同使用 JSON 对象,包括大多数的对象没有很多的二进制数据(如何使用 JavaScript 和 JSON 表示二进制数据,见第八章,使用 JSON 为二进制数据传输)。 这包括原始值(自文档化,因为每个值都伴随着一个属性)、带有简单值(包括映射)的平面对象,以及简单或复杂对象的数组。

JSON 的自文档特性使其成为开发新对象时进行数据传输的理想选择,尽管它不支持 XML 中可能存在的注释。 它的纯文本特性使得它可以使用流行的压缩方案(如gzip,在大多数 web 服务器和 web 客户端中可用)进行在线压缩,而且它的格式比冗长的 XML 更容易阅读。

提示

请注意,JSON 文档本质上是树,因此不支持周期性数据结构,比如图,其中一个节点指向相同数据结构中的另一个节点。

如果您使用正在使用的编程语言中的本机表示来创建这样的数据结构,并试图将其转换为 JSON,那么您将得到一个错误。

用 JavaScript 读写 JSON

JSON 起源于,是指在 web 服务器和 JavaScript 之间携带数据,所以让我们从一个简单的代码片段开始,在 web 浏览器中使用 JavaScript 读取和写入 JSON。 ,using JSON in AJAX Applications with jQuery and AngularJS; 接下来的内容是如何从 JSON 获取 JavaScript 对象以及如何从 JavaScript 对象创建 JSON 字符串。

准备好

你将需要一种方法来编辑 JavaScript,并在浏览器中运行它。 在这个例子中,几乎所有的例子在这本书中,我们将使用谷歌 Chrome。 您可以在https://www.google.com/chrome/browser下载谷歌 Chrome 浏览器。 一旦你安装谷歌 Chrome,你会想激活 JavaScript 控制台,点击右边的自定义并控制涂鸦 Chrome图标,它看起来像这样:

Getting ready

然后,你会想要去更多的工具| JavaScript 控制台。 你应该会在网页的一边看到一个 JavaScript 控制台,像这样:

Getting ready

如果你喜欢关键命令,您还可以使用Ctrl + Shift+在 Windows 和 Linux,或【显示】控制+选择+【病人】J Macintosh。

从开始,您可以在右下角输入 JavaScript,并按输入(在 Mac OS X 系统上返回)来评估 JavaScript。

How to do it…

现代的 web 浏览器,如 Chrome,在 JavaScript 运行时定义一个 JSON 对象,可以将包含 JSON 的字符串数据转换为 JavaScript 对象,并将 JavaScript 对象转换为 JSON。 下面是一个简单的例子:

>var json = '{"call":"KF6GPE","type":"l","time":
"1399371514","lasttime":"1418597513","lat":37.17667,"lng":
-122.14650,"result" : "ok" }';
<- "{ "call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat":37.17667,"lng":-122.14650,
"result" : "ok" }"
>var object = JSON.parse(json);
<- Object {call:"KF6GPE",type:"l",time:"1399371514",
lasttime:"1418597513",lat:37.17667, lng:-122.14650,result: "ok"}
> object.result
<- "ok"
>var newJson = JSON.stringify(object);
<- "{ "call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat": 37.17667,"lng": -122.14650,
"result" : "ok" }"

注释

在这个和后面的 JavaScript 示例中,你在 JavaScript 控制台中输入的文本前面是一个>符号,而 JavaScript 控制台打印的是任何以<-符号开头的内容。

How it works…

Chrome 和其他现代 web 浏览器定义了JSON对象,具有在包含 JSON 和 JavaScript 对象的字符串之间转换的方法。

在前面的示例中,我们首先将json变量的值设置为一个简单的 JSON 表达式,其中包含一个属性result,其值为ok。 JavaScript 解释器返回变量json的结果值。

下一行使用JSON方法parsejson引用的 JSON 字符串转换为 JavaScript 对象:

>var object = JSON.parse(json);
<- Object { call:"KF6GPE", type:"l", time:"1399371514", lasttime:"1418597513", lat:37.17667, lng:-122.14650, result: "ok"}

然后就可以访问对象中的任何值,就像访问其他 JavaScript 对象一样; 毕竟,它只是一个物体:

> object.result;
<- "ok"

最后,如果你需要将对象转换为 JSON,你可以使用JSON方法stringify:

>var newJson = JSON.stringify(object);
<- "{ "call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat": 37.17667,"lng": -122.14650,
"result" : "ok" }"

There's more…

关于这些方法,您应该知道两件事。 首先,如果你传递的 JSON 是畸形的,或者根本不是 JSON, parse 将抛出一个异常:

>JSON.parse('{"result" = "ok" }')
<- VM465:2 Uncaught SyntaxError: Unexpected token =

错误并不是很有帮助,但如果你正在调试一个不完全兼容和调试过的 JSON 编码器发送的 JSON,那么错误总比没有好。

其次,非常陈旧的 web 浏览器可能没有带有这些方法的 JSON 对象。 在这种情况下,你可以使用 JavaScript 函数eval后包装 JSON,像这样:

>eval('('+json+')')
<- Object {result: "ok"}

eval函数评估你作为 JavaScript 传递的字符串,JSON 符号实际上只是 JavaScript 的一个子集。 然而,出于一些原因,你应该尽量避免使用eval。 首先,它通常比JSON对象提供的方法慢。 第二,不安全; 您的字符串可能包含恶意的 JavaScript,它可能会崩溃或破坏您的 JavaScript 应用,这不是一个可以轻易应对的威胁。 使用JSON对象,只要它是可用的。 第三,您可以使用parsestringify方法来处理简单的值,如布尔值、数字和字符串; 您并不局限于前面示例中的键-值对。 如果我想要做的只是传递一个布尔值(比如“事务成功了!”),我可以这样写:

var jsonSuccess = 'true';
<- "true"
> var flag = JSON.parse(jsonSuccess);

最后,值得指出的是,JSON 的parsestringify方法都接受一个可选的替换函数,该函数在序列化或反序列化的对象中的每个键和值上被调用。 您可以使用此函数在解析 JSON 时执行实时数据转换; 例如,可以使用它在日期的字符串表示形式和从 epoch 开始的午夜开始的秒数之间进行转换,或者纠正字符串的大写。 我可以对转换的两边使用一个替换函数,如下面的代码所示,以使调用字段小写:

> var object = JSON.parse(json, function(k, v) {
  if ( k == 'call') return v.toLowerCase();
});
<- Object { call:"kf6gpe", type:"l", time:"1399371514",
lasttime:"1418597513", lat:37.17667, lng:-122.14650, result: "ok"}

您还可以返回undefined以从结果中删除一个项目; 为了从我生成的 JSON 中省略类型字段,我可以执行如下:

> var newJson = JSON.stringify(object, function (k, v) {
  if k == 'type') return undefined;
});
<- "{ "call":"KF6GPE","time":"1399371514","lasttime":
"1418597513","lat": 37.17667,"lng": -122.14650, "result" : "ok" 
}"

用 c++读写 JSON

c++是一种早于 JSON 的语言,但仍然与许多项目相关。 c++中没有对 JSON 的原生支持,但有许多库提供了对 JSON 的支持。 也许使用最广泛的是JsonCpp,可从 GitHub 网站https://github.com/open-source-parsers/jsoncpp获得。 它是在麻省理工学院许可或公共领域许可下使用的,所以实际上对它的使用没有限制。

准备好

要使用 JsonCpp,你需要先去网站下载压缩文件和整个库。 这样做之后,需要将其与应用的源代码集成。

如何将它与应用的源代码集成在不同的平台上是不同的,但一般的过程是这样的:

  1. 使用网站上的说明为库创建一个合并的源文件和标题。 为此,您需要下载 JsonCpp 并安装 Python 2.6 或更高版本。 在 JsonCpp 的顶层目录下,运行python amalgamate.py
  2. 在任何想要使用 JsonCpp 库的文件中包含 Include 文件dist/json/json.h
  3. 将源文件dist/jsoncpp.cpp包含在项目的 make 文件或构建系统中。

这样做之后,您应该可以访问任何包含json/json.h头文件中的 JsonCpp 接口。

How to do it…

下面是一个简单的 c++应用,它使用 JsonCpp 在std::string包含一些简单 JSON 和 JSON 对象之间进行转换:

#include <string>
#include <iostream>
#include "json/json.h"

using namespace std;

int main(int argc, _TCHAR* argv[])
{
  Json::Reader reader;
  Json::Value root;

  string json = "{\"call\": \"KF6GPE\",\"type\":\"l\",\"time\":
  \"1399371514\",\"lasttime\":\"1418597513\",\"lat\": 37.17667,
  \"lng\": -122.14650,\"result\":\"ok\"}";

  bool parseSuccess = reader.parse(json, root, false);

  if (parseSuccess)
  {
    const Json::Value resultValue = root["result"];
    cout << "Result is " << resultValue.asString() << "\n";
  }

  Json::StyledWriter styledWriter;
  Json::FastWriter fastWriter;
  Json::Value newValue;
  newValue["result"] = "ok";

  cout << styledWriter.write(newValue) << "\n";
  cout << fastWriter.write(newValue) << "\n";

  return 0;
}

How it works…

本示例首先包含必要的 include,包括json/json.h,它定义了 JsonCpp 的接口。 为了简洁起见,我们显式地引用了std名称空间,但没有对Json名称空间这样做,因为 JsonCpp 在其中定义了它的所有接口。

JsonCpp 实现定义了Json::ReaderJson::Writer,分别指定了 JSON 读写器和写入器的接口。 实际上,Json::Reader接口也是一个 JSON 类的实现,该类可以读取 JSON,返回其值为Json::Value。 变量只是定义了一个接口; 你会想使用它的一个子类,如Json::FastWriterJson::StyledWriterJson::Value对象创建 JSON。

前面的列表首先定义Json::ReaderJson::Value; 我们将使用阅读器读取下一行定义的 JSON,并将其值存储在Json::Value变量root中。 (大概你的 c++应用会从另一个来源获得 JSON,比如 web 服务或本地文件。)

解析 JSON 就像调用阅读器的parse函数一样简单,传递 JSON 和Json::Value,然后将 JSON 值写入其中。 它返回一个布尔值,如果 JSON 解析成功,则返回true

Json::Value类表示 JSON 对象为树; 单个值由原始 JSON 中的属性名引用,这些值是那些键的值,可以通过asString等方法访问,asString方法返回对象的值作为本地 c++类型。 Json::Value的这些方法包括:

  • asString返回std::string
  • asInt返回Int
  • asUInt返回UInt
  • asInt64返回Int64
  • asFloat返回float
  • asDouble返回double
  • asBool返回bool

此外,该类提供了operator[],允许您访问数组元素。

你也可以使用以下方法查询一个Json::Value对象来确定它的类型:

  • isNull,当值为null时返回true
  • isBool,当值为bool时返回true
  • isInt,当值为Int时返回true
  • isUInt,当值为UInt时返回true
  • isIntegral,如果是整数,返回true
  • isDouble,当值为double时返回true
  • isNumeric,如果值是数字,返回true
  • isString,如果是字符串,返回true
  • isArray,如果是数组则返回true
  • isObject,如果值是另一个 JSON 对象(可以使用另一个Json::Value值进行分解)则返回 true

无论如何,我们的代码使用asString获取编码为result属性的std::string值,并将其写入控制台。

代码然后定义Json::StyledWriterJson::FastWriter以创建一些漂亮打印的 JSON 和未格式化的 JSON 字符串,作为以及单个Json::Value对象,以包含新的 JSON。 将内容赋给 JSON 值很简单,因为用适当的实现覆盖了operator[]operator[]=方法,将标准 c++类型转换为 JSON 对象。 所以,以下代码创建一个 JSON 属性/值对的属性设置为result,和值设置为ok(尽管这段代码不显示它,您可以创建 JSON 属性-值对的树木将 JSON 对象分配给其他 JSON 对象):

newValue["result"] = "ok";

我们首先使用StyledWriter,然后使用FastWriternewValue中编码 JSON 值,将每个字符串写入控制台。

当然,您也可以将单个值传递给 JsonCpp; 如果你只是想传递一个双精度数字,没有理由不执行以下代码:

Json::Reader reader;
Json::Value piValue;

string json = "3.1415";
bool parseSuccess = reader.parse(json, piValue, false);
  double pi = piValue.asDouble();

参见

对于 JsonCpp 的文档,您可以从http://www.stack.nl/~dimitri/doxygen/安装 doxygen,并在主 JsonCpp 发行版的doc文件夹中运行它。

还有其他 JSON 转换实现的 c++,太。 完整的列表请参见http://json.org/

用 c#读写 JSON

c#是一种通用的客户端语言,用于丰富的应用,以及编写运行在 ASP.NET 上的 web 服务的客户端实现。 . net 库在 System.Web.Extensions 程序集中包含 JSON 序列化和反序列化。

准备好

这个示例使用了 System.Web.Extensions 程序集中的内置 JSON 序列化器和反序列化器,这是许多可用的。net 库之一。 如果你已经安装了 Visual Studio 的最新版本(参见https://www.visualstudio.com/en-us/downloads/visual-studio-2015-downloads-vs.aspx),那么它应该是可用的。 使用这个大会所有您需要做的是包括在应用引用的程序集在 Visual Studio 通过右键单击引用项目在您的项目中,选择添加引用,并向下滚动【显示】System.Web.Extensions框架程序集列表中。

How to do it…

下面是一个简单的应用,它将一些 JSON 反序列化为属性-对象对的字典:

using System;
using System.Collections.Generic;
using System.Web.Script.Serialization;

namespace JSONExample
{
    public class SimpleResult
    {
        public string result;
    }

    class Program
    {
        static void Main(string[] args)
        {
            JavaScriptSerializer serializer = 
            new System.Web.Script.Serialization.
            JavaScriptSerializer();

            string json = @"{ ""call"":""KF6GPE"",""type"":
""l"",""time"":""1399371514"",""lasttime"":""1418597513"",
""lat"": 37.17667,""lng\": -122.14650,""result"": ""ok"" }";

dynamic result = serializer.DeserializeObject(json);
            foreach (KeyValuePair<string, object> entry in result)
            {
                var key = entry.Key;
                var value = entry.Value as string;
Console.WriteLine(String.Format("{0} : {1}", 
key, value));
            }
            Console.WriteLine(serializer.Serialize(result));

            var anotherResult = new SimpleResult { result="ok" };
            Console.WriteLine(serializer.Serialize(
            anotherResult));
        }
    }
}

How it works…

extensions 程序集提供了System.Web.Script.Serialization命名空间中的JavaScriptSerializer类。 这段代码首先定义一个简单的类SimpleResult,我们将在示例中将其编码为 JSON。

Main方法首先定义一个JavaScriptSerializer实例,然后string包含我们的 JSON。 解析 JSON 就像调用JavaScriptSerializer实例的DeserializeObject方法一样简单,该方法返回一个对象,其类型是在运行时根据传递的 JSON 确定的。

提示

您还可以使用DeserializeObject以类型安全的方式解析 JSON,然后返回对象的类型与传递给方法的类型匹配。 我将在第 7 章中向你展示如何使用 JSON 的类型安全方式

DeserializeObject返回键值对的Dictionary; 键是 JSON 中的属性,值是表示这些属性值的对象。 在我们的示例中,我们只是遍历字典中的键和值,并打印每个键和值。 因为我们知道 JSON 中值的类型,所以我们可以使用 c#as关键字将其强制转换为合适的类型(在本例中是string); 如果不是string,我们会收到null的值。 您可以使用as或 c#的类型推断来确定 JSON 中未知对象的类型,从而轻松解析缺乏严格语义的 JSON。

JavaScriptSerializer类还包括Serialize方法; 您可以将其作为属性-值对的字典传递,就像我们对反序列化结果所做的那样,或者您可以将其作为 c#类的实例传递。 如果您将它作为一个类传递,它将尝试通过内省类字段和值来序列化类。

There's more…

微软提供的 JSON 实现足以满足的许多用途,但不一定是您的应用的最佳选择。 其他开发者已经实现了更好的,它们通常使用与微软相同的接口。 一个不错的选择是 Newtonsoft 的 Json。 你可以在http://json.codeplex.com/或从 Visual Studio 中的 NuGet 获得。 它支持更广泛的. net 平台(包括 Windows Phone)、LINQ 查询、针对 JSON 的类似 xpath 的查询,并且比微软的实现更快。 使用它类似于使用 Microsoft 实现:从 Web 或 NuGet 安装包,将程序集的引用添加到应用中,然后使用NewtonSoft.Json名称空间中的JsonSerializer类。 它定义了与 Microsoft 实现相同的SerializeObjectDeserializeObject方法,使切换到这个库变得容易。 詹姆斯·牛顿·金Json 的作者。 NET,使其在 MIT 许可下可用。

与其他语言一样,您也可以通过反序列化和序列化过程携带基本类型。 例如,在计算以下代码后,得到的动态变量piResult将包含一个浮点数 3.14:

string piJson = "3.14";
dynamic piResult = serializer.DeserializeObject(piJson);

参见

如前所述,您可以以类型安全的方式完成此操作; 我们将在第 7 章中详细讨论。 您将使用泛型方法DeserializeObject<>来完成这一操作,传递您想要反序列化为的类型的类型变量。

用 Java 读写 JSON

Java 和 c++一样,比 JSON 早。 Oracle 目前正在为 Java 添加 JSON 支持,但与此同时,Web 上有几种提供 JSON 支持的实现。 类似于你在本章之前看到的 c++实现,你可以使用第三方库在 JSON 和 Java 之间进行转换; 在本例中,打包为 Java 归档(JAR)文件,其实现通常将 JSON 对象表示为命名对象树。

也许 JSON 解析的最佳 Java 实现是 Gson,可以从谷歌的http://code.google.com/p/google-gson/获得,该功能是在 Apache License 2.0 下许可的。

准备好

首先,你需要找到 Gson; 您可以通过使用 SVN 通过 HTTP 对存储库进行只读签出,使用以下命令:

svn checkout http://google-gson.googlecode.com/svn/trunk/google-gson-read-only

当然,这假设您有一个 Java 开发工具包(http://www.oracle.com/technetwork/java/javase/downloads/index.html)和 SVN (TortoiseSVN 是一个好的客户端为 Windows http://tortoisesvn.net/downloads.html)安装。 许多 Java ide 都支持 SVN。

签出代码后,按照代码附带的说明构建 Gson JAR 文件,并将 JAR 文件添加到项目中。

How to do it…

首先,您需要创建一个com.google.gson.Gson对象。 这个类定义了用于在 JSON 和 Java 之间转换的接口:

Gson gson = new com.google.gson.Gson(); 
String json = "{\"call\": \"KF6GPE\", \"type\": \"l\", \"time\":
\"1399371514\", \"lasttime\": \"1418597513\", \"lat\": 37.17667,
\"lng\": -122.14650,\"result\":\"ok\"}";
com.google.gson.JsonObject result = gson.fromJson(json, 
JsonElement.class).getAsJsonObject(); 

类定义了包含 JSON 对象的顶级对象; 你可以使用它的getadd方法来获取和设置属性,如下所示:

JsonElement result = result.get("result").getAsString();

Gson 库使用JsonElement类封装单个 JSON 值; 它有以下方法,让您获得JsonElement中包含的值作为普通 Java 类型:

  • getAsBoolean,返回值为Boolean
  • getAsByte,返回值为byte
  • getAsCharacter,返回值为char
  • getAsDouble,返回值为double
  • getAsFloat,返回值为float
  • getAsInt,返回值为int
  • getAsJsonArray,返回值为JsonArray
  • getAsJsonObject,返回值为JsonObject
  • getAsLong,返回值为long
  • getAsShort,返回值为short
  • getAsString,返回值为String

和可以通过以下方法了解JsonElement中的类型:

  • isJsonArray,如果元素是一个对象数组,则返回true
  • isJsonNull,如果元素为空则返回true
  • isJsonObject,如果元素是复合对象(另一棵 JSON 树)而不是单一类型,则返回true
  • isJsonPrimitive,如果元素是基本类型,如数字或字符串,则返回 true

There's more…

你也可以直接将类的实例转换为 JSON,可以这样写:

public class SimpleResult {
    public String result;
}

// Elsewhere in your code…
Gson gson = new com.google.gson.Gson(); 
SimpleResult result = new SimpleResult;
result.result = "ok";
String json = gson.toJson(result);  

这定义了一个类SimpleResult,我们用它来创建单个实例,然后使用Gson对象实例使用Gson方法toJson将其转换为包含 JSON 的字符串。

最后,因为JsonElement封装了单个值,你也可以处理 JSON 中表示的简单值,像这样:

Gson gson = new com.google.gson.Gson(); 
String piJson = "3.14";
double result = gson.fromJson(piJson, 
JsonElement.class).getAsDouble(); 

这将 JSON 中的原始值3.14转换为 Javadouble

参见

就像 c#例子一样,你可以以类型安全的方式直接将从 JSON 转换为普通的旧 Java 对象(POJO)。 您将在第 7 章中看到如何使用 JSON 的类型安全

Java 还有其他的 JSON 转换实现。 完整的列表请参见http://json.org/

用 Perl 读写 JSON

Perl 先于 JSON,虽然有一个很好的 JSON 转换的实现,可从 CPAN,综合 Perl 归档网络。

How to do it…

首先,从 CPAN 下载 JSON 模块并安装它。 通常,您将下载文件,解压缩它,然后在一个已经有 Perl 的系统上运行以下代码并进行配置:

perl Makefile.PL 
make 
make install

下面是一个简单的例子:

use JSON;
use Data::Dumper;
my $json = '{ "call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat": 37.17667,"lng": -122.14650,
"result" : "ok" }';
my %result = decode_json($json);
print Dumper(result);
print encode_json(%result);

让我们看看 JSON 模块提供的接口。

How it works…

CPAN 模块分别定义了对 JSON 进行解码的decode_jsonencode_json方法。 这些方法在 Perl 对象(例如文字值和关联数组)和包含 JSON 的字符串之间相互转换。

代码首先导入 JSON 和Data::Dumper模块。 接下来,它定义了一个字符串$json,其中包含我们想要解析的 JSON。

对于$json中的 JSON,我们定义%result为包含 JSON 中定义的对象的关联数组,将 hash 中的值转储到下一行。

最后,我们将哈希重新编码为 JSON,并将结果打印到终端。

参见

了解更多信息,下载 JSON CPAN 模块,请访问https://metacpan.org/pod/JSON

Python JSON 读写

Python 有对 JSON 的原生支持,从 Python 2.6 开始,通过json模块。 使用模块就像使用import语句导入模块,然后通过它定义的json对象访问编码器和解码器一样简单。

准备好

只需在源代码中输入以下内容,就可以引用 JSON 功能:

import json

How to do it…

下面是来自 Python 解释器的一个简单示例:

>>> import json
>>>json = '{ "call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat": 37.17667,"lng": -122.14650,
"result" : "ok" }'
u'{"call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat": 37.17667,"lng": -122.14650,
"result": "ok" }'
>>>result = json.loads(json)
{u'call':u'KF6GPE',u'type':u'l',u'time':u'1399371514',
u'lasttime':u'1418597513',u'lat': 37.17667,u'lng': -122.14650,u'result': u'ok'}
>>> result['result']
u'ok'
>>> print json.dumps(result)
{"call":"KF6GPE","type":"l","time":"1399371514",
"lasttime":"1418597513","lat": 37.17667,"lng": -122.14650,
"result":"ok"}
>>> print json.dumps(result, 
...                  indent=4)
{
"call":"KF6GPE",
"type":"l",
"time":"1399371514",
"lasttime":"1418597513",
"lat": 37.17667,
"lng": -122.14650,
    "result": "ok"
}

让我们进一步看一下loadsdumps

How it works…

Python 通过它的对象层次结构对关联数组有很大的支持。 json模块提供了一个json对象,该对象具有loadsdumps方法,可将文本字符串中的 JSON 转换为关联数组,将关联数组转换为文本字符串中的 JSON。 如果你熟悉 Pythonmarshalpickle模块,界面是类似的; 您可以使用loads方法从 JSON 表示中获取 Python 对象,使用dumps方法将对象转换为等效的 JSON。

前面的清单就是这样做的。 它定义了一个包含 JSON 的变量j,然后使用json.loads获取一个 Python 对象result。 JSON 中的字段可以作为生成的 Python 对象中的命名对象来访问。 (注意,我们不能调用 JSON 字符串json,因为它会影响模块接口的定义。)

为了转换成 JSON,我们使用了json.dumps方法。 默认情况下,dumps创建了一个紧凑的机器可读 JSON 版本,其中包含最少的空格; 这最适合用于有线传输或存储在文件中。 当你调试你的 JSON 时,它会帮助你用缩进和分隔符周围的一些空白来美化它; 你可以使用可选的indentseparators参数。 参数indent表示每个连续嵌套的对象在字符串中缩进的空格数,separators表示每个对象之间、属性和值之间的分隔符。

参见

有关json模块的更多文档,请参阅 Python 文档https://docs.python.org/2/library/json.html。****