【原创】各种 JSON 解析库的功能简介
【原创】各种 JSON 解析库的功能简介
摩云飞 发表于5年前
【原创】各种 JSON 解析库的功能简介
  • 发表于 5年前
  • 阅读 7851
  • 收藏 8
  • 点赞 1
  • 评论 0
摘要: 比较 JSON 官网给出的C/C++语言实现的库

这里增加一项无聊的对比图,看客自斟。


=================================== 
rui_maciel/mjson
Last Update:2013-05-15(最新版本为 mjson-1.5 发布日期为 2012-08-22)
description

M's JSON parser is a small JSON parser written in ISO C which enables the user to handle information described by the JSON data interchange format.
mjson 解析器是一个使用 ISO C 实现的小型 JSON 解析器。

M's JSON parser is a library entirely written in ISO C which offers a way to access data that has been encoded according to the JSON document format. This is accomplished by offering programmers an easy and convenient way to parse any given JSON document and, based on the information which is extracted from these documents, creating a document tree structure that reflects exactly the contents of each JSON document.
After a JSON document is parsed, all a programmer needs to do to access the information stored in a JSON document is to traverse the tree structure which was created by the parser and access any attribute associated with any JSON value.
Once this information is accessed, the memory which has been allocated to the JSON document tree structure can be safely freed.

作者提供的测试用例:examples(存在一些问题,需要自行调整代码)

一句话总结:
  • 该库可以很方便的集成到其他项目中,支持跨平台;
  • 该库支持 SAX-like 解析;支持从文本文件中按行获取数据进行解析;
  • 支持 UTF-8;
  • 支持 pretty 格式和 raw 格式的 json 数据相互转换;
  • 针对 json 数据中特定节点数据的搜索功能基本不可用(这个比较恶心)

=================================== 
william/libjson
Last Update:2013-09-27
description

json.c is a JSON C library that supports path autovivification and conversion. Autovivified and converted paths greatly simplify manipulation of JSON trees, allowing one to discard most bothersome boilerplate code.
json.c 作为 JSON 的 C 库实现,支持 path autovivification 和 conversion 功能。这两项功能极大的简化了针对 JSON 树结构上的各种操作,允许你在代码编写过程中避免大量让人讨厌的“样板”代码。

Because "JSON schema" is something of an oxymoron, the library makes the presumption that you mean what you say; that the schema is whatever the code does. If you attempt to write through a non-existent or type-incompatible path, the library fixes the tree to accomodate the request, rather than punt back to the caller. Likewise, a read through a non-existent or type-incompatible path returns a sane, default value—specifically 0 or an empty string.
因为“JSON schema”是一个容易让人搞不清楚的东西,所以在该库的实现中作了如下假定:你怎样描述就是怎样的结果;代码的动作决定 schema 的模样。如果你企图在一个不存在,或者类型不兼容的 json 路径上写穿(可以理解为强迫写),该库会按照你的 request 对树结构进行相应的修正,而不是什么都不干就返回到调用者处。同样地,对一个不存在的,或者类型不兼容的 json 路径进行读穿,将会得到恒定不变的默认值 - 一般是 0 或者空字串。

In addition, a stack interface allows changing the current root. This makes descending up and down the tree more convenient, and eases abstraction as code which reads or writes subtrees need not be concerned with the path to that particular subtree.
另外,通过 stack interface 可以方便的更改当前的 root 位置。这也使得在树结构上进行上下移动变得更加容易,并提供了更为简单的代码级抽象 -- 在读或者写子树结构时无需关心与该子树对应的路径。

Both the parser and composer are restartable and operate over a series of caller provided input and output buffers. This is intended to ease integration with networked I/O environments, particularly non-blocking environments. JSON data can be both parsed and composed byte-by-byte without any intermediate, internal buffers. No callback schemes are used as half measures, so the user code needn't arbitrarily split blocks of code between different halves of a parse or compose operation.
解析器和生成器均具有 restartable 的特点,可以同时为不止一个调用者提供输入输出缓冲。这个设计的目的是为了简化在网络 I/O 环境应用时的集成工作,特别是用于非阻塞环境下。JSON 数据可以按逐字节方式解析和生成,并且无需任何中间或者内部缓冲。回调处理被设计成不会在 JSON 数据解析和生成过程中同时触发,故用户代码块的执行不会因此出现从解析部分变换到生成部分的过程,反之亦然。

json.c is implemented in a single source file, along with a companion header which defines the API. The only dependency is llrb.h.
该 json 库主要由 json.c 和 json.h 构成,唯一的外部依赖是 llrb.h 文件。

usage
用法

The API is broken up into three main sections. The grouping of declarations in the header reflects this, and makes for relatively easy perusal.
API 主要分成 3 个主要部分。可以从头文件中的分组声明看出。

The core API consists of routines to construct a JSON context object, and to parse and compose JSON data.
核心 API 包括:构造 JSON 上下文对象的 API、解析 JSON 数据的 API、生成 JSON 数据的 API。

The second set consists of routines to manipulate JSON value objects directly, although this is mostly used internally.
第二部分包括:直接操作 JSON value 对象的 API(大部分情况下仅在库内部调用)。

The third consists of routines which access and manipulate the JSON tree through a path expression. Objects are accessed with a dot ("."), arrays indexed by square brackets ("[", "]"). String interpolation is accomplished using the special character "$" and index interpolation using "#", along with their respective arguments (char pointer or int) in the passed variable argument list. The syntax uses the standard backslash escaping protocol.
第三部分包括:通过路径表达式访问和操作 JSON 树结构的 API。object 的访问通过点操作符(“.”);array 的索引通过中括号实现(“[”,“]”);字符串内的插值操作使用特殊字符“$”;array 索引的插值操作使用特殊字符“#”。最后两个插值操作需要同时提供相应的参数列表(字符串指针或者整形变量)。整体的语法规则使用了标准的反斜杠转义协议。

The core API returns errors directly, while most of the remainder signal errors using longjmp(). The macro pair json_enter()/json_leave() are analogous to try/finally. However, thrown errors need not be caught; aren't thrown unless an exception context is provided; consistency is maintained if errors are ignored; and a sane and safe value always returned when reading a value. json.c error codes are negative numbers in the range JSON_EBASE to JSON_ELAST, and communicated along with system error codes through a single int value. POSIX guarantees system codes to be positive.
在设计上,核心 API 会直接返回错误信息,而其他大部分 API 是采用 longjmp() 方式来通知错误的发生。json_enter()/json_leave() 这对宏功能上类似与 try/finally 。然而,抛出的错误是不需要进行捕获的;仅在具有异常上下文的时候抛出异常;在错误信息被忽略的情况下能够保证数据的一致性;在读值操作中总能保证返回一个不会变化的安全值。json.c 中的错误码是范围在 JSON_EBASE 到 JSON_ELAST 之间的负数。

A small regression utility can be built from the source. Defining JSON_MAIN will expose the main() definition, and until documentation can be written usage can be gleaned from the implementation of the utility commands. The utility requires libffi in order to dynamically construct calls with interpolating path expressions, useful for exercising path evaluation. However, the include path for the libffi header is hit-and-miss. And a bug report has been filed with Apple because clang chokes on their broken ffi.h header.
小型的回归测试类应用可以直接在该源文件的基础上进行。

一句话总结:
      库本身支持的功能绝对有亮点,但由于原作者对 C99 标准贯彻的非常坚决,所以将上述代码移植到不支持 C99 标准的 VS 上非常困难。

=================================== 
Jansson
Last Update:2013-09-23
Description:
Jansson is a C library for encoding, decoding and manipulating JSON data. It features:
Jansson 以 C 库的形式提供了针对 JSON 数据编码、解码和操纵的能力。
  • Simple and intuitive API and data model 提供简单直观的 API 以及数据模型
  • Comprehensive documentation 全面的文档
  • No dependencies on other libraries 无第三方库依赖
  • Full Unicode support (UTF-8) 对 Unicode 的完全支持(UTF-8 等)
  • Extensive test suite 完整的测试集
  • Jansson is licensed under the MIT license. 以 MIT 许可证发布

=================================== 
vincenthz/libjson

Last Update:2013-09-23(上一个 stable 版本为 v0.8,发布于 2010-09-04)
Description:
libjson is a small C library and small codebase that packs an efficient parser and a configurable printer. libjson is covered by the LGPLv2 license, or at your option the LGPLv3 license.
一个小巧的 C 库,封装了高效的解析器和可配置的 printer 用于输出。
libjson is a simple library without any dependancies to parse and pretty print the json format (RFC4627). 
无第三方库依赖。

Here's the feature of libjson:
  • Interruptible parser: get the JSON data to the parser any way you want; by appending char by char, or string chunks, the input reading is completely left to the caller.
  • No object model integrated: easy integration with any model by the means of a simple callback.
  • Small codebase: handcoded parser and efficient factorisation make the code smalls.
  • Fast: use efficient code, and small parsing tables to not do any extra work and remains as fast and efficient as possible.
  • Full JSON support: tested through a small and precise testsuite.
  • No native conversion: callback only string of data and leave the actual representation of data to the caller
  • Supports putting limits on nesting level. security against DoS over very deep data.
  • Supports putting limits on data (string/int/float) size. security against DoS over very large data object.
  • Optionally support YAML/python comments and C comments.
  • Supports projects-specific allocation functions to integrate completely with projects
  • jsonlint utility provided with the library to verify, or reformat json stream. also useful as example on how to use the library.
libjson parser is an interruptible handcoded state parse. the parser takes character or string as input. Since it's interruptible, it's up to the user to feed the stream to the parser, which permits complete flexibility as to whether the data is coming from a pipe, a network socket, a file on disk, a serial line, or crafted by the user.
该 libjson 库中提供的 json 解析器支持解析过程可中断的特性,即解析器既可以按字符处理,也可以按字串处理。换句话说,使用者可以为该解析器指定任意的、待解析的、数据流的源,如从 pipe、网络socket、磁盘文件、串行线路,以及使用者精心设计的什么东东。

The parser doesn't create an object tree for you, but each time it comes up with an element in this data, it just callback to the user with the type found and for some type, the data associated with it. It can be compared to the SAX way of XML, hence it's called SAJ (Simple API for JSon).
该解析器不会为你创建 object 树结构,而是通过回调函数每次向你提供一个属于该树中的元素,包括元素的类型,以及可能存在的数据值。这种能力与 XML 中的 SAX 类似,所以可以称作 SAJ(Simple API for JSon)。

The parser doesn't convert number to any native C format, but instead callback with a string that is a valid JSon number. JSon number can be of any size, so that's up to user to decide whetever or not, the number can map to native C type int32_t, int64_t, or a complex integer type. As well the user has a choice to refuse the integer at the callback stage if the length is not appropriate.
该解析器没有对 json 中的 number 类型值进行本地 C 格式的转换,而是在回调函数中以字串的形式将 number 类型值返回。json 中的 number 类型没有对数据值的范围做限制,所以 number 类型值能否被正确映射到本地 C 类型,如 int32_t、int64_t,或更复杂的整数类型,由用户自己来确定。所以,这也就让用户有机会在调用回调函数处理时,通过判定当前 number 数值能否被正确处理,决定是拒绝还是接收该数据结果。

The parser optionally allows YAML and/or C comments to be ignored if the config structure is set accordingly, otherwise a JSON_ERROR_COMMENT_NOT_ALLOWED is returned.

一句话总结:
      没有提供搜索特定值的接口。

=================================== 

jsoncpp-src-0.5.0.tar.gz

Last Update: 2012-12-20 -> 2013-09-23
Description:

jsoncpp is an implementation of a JSON (http://json.org) reader and writer in C++. JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.

反面观点:

Posted by OpenID User — 2012-03-14 It's really good apart from the lack of UNICODE support, I'd have to change everything to TCHAR and std::wstring :(
Posted by Sergey Kolomenkin — 2011-02-09 It corrupts heap memory! Developers don't correct even critical bugs for a months (see bug list).
Posted by hypernewbie — 2010-06-16 absolutely horrendous. making a Json::Value global would result in a pure virtual function call crash upon exit. If you try asInt() when the value is a string, you'd get a huge assertion fail. Random access violations everywhere.

网友经验:

1.《json笔记-jsoncpp一个全局对象的bug》,指出由于全局对象构造和析构时可能引发崩溃的问题。2.《C++ Json》,文档整理的比较干净,对 Value 值类型详细进行了代码举例。
3.《JsonCpp使用优化》,从 编译、使用方式、代码,以及编译成哪种库几方面说明优化问题。
4.《JsonCpp简介》,可以看下工程组织方式,和测试例子。

实践经验:

1.解压后的包内容如下:

2.查看 README 文件,并按其中的要求下载并安装配置 scons-local 和 python 。其中 scons-local 解压后,令 scons.py 与 README 位于同级目录。如下图:

3.执行工程配置和编译命令:

python scons.py platform=PLTFRM [TARGET]
其中
where PLTFRM may be one of:
	suncc Sun C++ (Solaris)
	vacpp Visual Age C++ (AIX)
	mingw 
	msvc6 Microsoft Visual Studio 6 service pack 5-6
	msvc70 Microsoft Visual Studio 2002
	msvc71 Microsoft Visual Studio 2003
	msvc80 Microsoft Visual Studio 2005
	linux-gcc Gnu C++ (linux, also reported to work for Mac OS X)
and TARGET may be:
	check: build library and run unit tests.
另外,如果你要编译 VS2008 或 VS2010 的库,则需要在 Sconstruct 文件中做相应的修改,很简单的。

4.执行命令后的结果,如下图:


==================================

json-parser-master.zip

Last Update: 2012-12-09 -> 2013-10-09
README.md

Very low footprint JSON parser written in portable ANSI C. BSD licensed with no dependencies (i.e. just drop the C file into your project) Never recurses or allocates more memory than it needs Very simple API with operator sugar for C++


个人总结:
1.目录结构

2.提供的 API

json_parse 封装了对 json_parse_ex 的调用

json_value * json_parse(const json_char * json);

json_parse_ex 封装了对 new_value 和 json_value_free 的调用

json_value * json_parse_ex(json_settings * settings, 
                           const json_char * json, char * error);
new_value 封装了对 json_alloc 的调用
static int new_value(json_state * state, json_value ** top, 
                     json_value ** root, json_value ** alloc, json_type type);
释放json值
void json_value_free(json_value *);
内存分配处理
static void * json_alloc(json_state * state, unsigned long size, int zero);


================================== 

rapidjson-0.11.zip

Last Update: 2012-11-16 -> 无更新
Description

Rapidjson is an attempt to create the fastest JSON parser and generator.
  1. Small but complete. Supports both SAX and DOM style API. SAX parser only a few hundred lines of code.
  2. Fast. In the order of magnitude of strlen(). Optionally supports SSE2/SSE4.2 for acceleration.
  3. Self-contained. Minimal dependency on standard libraries. No BOOST, not even STL.
  4. Compact. Each JSON value is 16 or 20 bytes for 32 or 64-bit machines respectively (excluding text string storage). With the custom memory allocator, parser allocates memory compactly during parsing.
  5. Full  RFC4627 compliance. Supports UTF-8, UTF-16 and UTF-32.
  6. Support both in-situ parsing (directly decode strings into the source JSON text) and non-destructive parsing (decode strings into new buffers).
  7. Parse number to int/unsigned/int64_t/uint64_t/double depending on input
  8. Support custom memory allocation. Also, the default memory pool allocator can also be supplied with a user buffer (such as a buffer allocated on user's heap or programme stack) to minimize allocation.

其他网友的点评:《推荐一款cpp解析json工具-rapidjson
其中给出的结论如下。
优点:

  • 依赖库很少;
  • 轻量级;
  • 对于 Dom 模型层级关系表述的很清楚。

缺点:

  • 只支持标准的 json 格式,一些非标准的 json 格式不支持;
  • 缺少一些比较通用的接口,再解析的时候需要自己再封装一层,否则代码量将会很大。

库作者同时提供了比较详细的用户手册供参考。
最后引用一段用户手册中的说明:

rapidjson is a header-only library. That means, the only thing to be done is to copy rapidjson/include/rapidjson and its sub-directories to your project or other include paths.


================================== 

json-c-0.10.tar.gz

Last Update: 2012-05-30 -> 2013-09-11

Overview

JSON-C implements a reference counting object model that allows you to easily construct JSON objects in C, output them as JSON formatted strings and parse JSON formatted strings back into the C representation of JSON objects.


================================== 

cJSONFiles.zip

Last Update: 2011-10-10 -> 2013-08-19
Description

An ultra-lightweight, portable, single-file, simple-as-can-be ANSI-C compliant JSON parser, under MIT license.

反面观点:

Posted by zhou meng — 2010-04-13 Lightweight, easy to use and well documented. Good work! Only not support wide byte like japanese,chinese
Posted by Otto Linnemann — 2010-01-24 Lightweight, easy to use and well documented. Good work! Only memory management should be improved!

==================================

ninja9578/libjson_7.6.1.zip
Last Update: 2012-06-25 -> 没有更新
Description

A JSON reader and writer which is super-effiecient and usually runs circles around other JSON libraries. It's highly customizable to optimize for your particular project, and very lightweight. For Windows, OSX, or Linux. Works in any language.

Features

  • Lazy or aggressive JSON Parsing
  • 100% JSON compliant
  • Language independent C interface
  • C++ interface
  • Test Suite and Example Projects
  • C and Bash style comment support
  • Automated install via make
  • cplusplus.com - style documentation
  • Streaming ability
  • Security to prevent various forms of Denial of Service

反面意见:

Posted by hu junjie — 2011-07-14
many bugs..
1:
case JSON_TEXT('\v'): //vertical tab res += JSON_TEXT("\\v"); break; case JSON_TEXT('\''): //apostrophe res += JSON_TEXT("\\\'"); break; in rfc4627, '\v', '\'' NOT NEED escape, if do this, other jsonlib will crash, ex: jsoncpp..
2:
json SHOULD transfer in utf8, if define UNICODE, will transfer unicode, if not define UNICODE, libjson can not parse string contant \uxxyy when xx not equ 0
3:
in code JSONWork.cpp *runner++ = (*++p == JSON_TEXT('\"')) ? JSON_TEXT('\1') : *p; //an escaped quote will reak havoc will all of my searching functions, so change it into an illegal character in JSON for convertion later on but iif the node no fetch yet, will not convertion later on, for example: const char *str = "{ \"mt\":\"\\\"str\\\"\" }" // str={"mt":"\"str\""} JSONNode obj = libjson::parse(str); json_string objstr = obj.write(); printf("%s\n", objstr.c_str()); WILL OUTPUT {"mt","\1str\1"}

=============================================

      另外,有网友专门对 C 代码的 JSON 解析库进行了比较,参考文章:《四种json c parser的兼容性比较》。
其给出的结论如下:

  1. 从各个通过的文件数量看, json-c 兼容性是最好的;
  2. mjson 和 json-parser 只有一两个文件,适合放到单个模块里用;
  3. json-c 采用 autoconf , 适合库形式;
  4. yajl 采用 cmake , 测试做的比较好;
  5. mjson 和 yajl 都支持 sax 事件解析方法。



标签: JSON
共有 人打赏支持
粉丝 360
博文 352
码字总数 952596
×
摩云飞
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: