json.c 是一个小型的 C 语言的 JSON 解析库,支持路径表达式、autovivification, 和 restartable I/O.而库的做者作了更为丰富的表述(中英对照翻译以下):
/* Generate the first example JSON snippet from RFC 4627: * * { * "Image": { * "Width": 800, * "Height": 600, * "Title": "View from 15th Floor", * "Thumbnail": { * "Url": "http://www.example.com/image * "Height": 125, * "Width": "100" * }, * "IDs": [116, 943, 234, 38793] * } * } */ #include "json.h" int main(void) { struct json *J; int error; J = json_open(JSON_F_NONE, &error); // 1.建立顶层object // 2.建立Image 为object // 3.建立Thumbnail为string其值为null value // 4.将下一操做的root定位在.Image.Thumbnail上 json_push(J, ".Image.Thumbnail"); /* automatically instantiates . as an object, .Image as an object, * and .Image.Thumbnail as a null value. .Image.Thumbnail is now the * root node for path expressions. */ // 1.自动将Thumbnail从value转变为object // 2.在Thumbnail下建立Url为string并设置其值也为string json_setstring(J, "http://www.example.com/image/481989943", "Url"); /* 是否应该为".Url" */ /* automatically converts .Image.Thumbnail to an object and * instantiates .Image.Thumbnail.Url to a string */ // 在Thumbnail下建立Height为string并设置其值为number // 在Thumbnail下建立Width为string并设置其值为string json_setnumber(J, 125, ".Height"); json_setstring(J, "100", ".Width"); // 切回document root json_pop(J); /* Our root node for path expressions is again the document root */ // 在Image下建立Width为string并设置其值为number // 在Image下建立Height为string并设置其值为number // 此时root应该被定位到.Image上 json_setnumber(J, 800, ".Image.Width"); json_setnumber(J, 600, ".Image.Height"); // 经过字符串插值方式在Image下建立Title为string并设置其值为string json_setstring(J, "View from 15th Floor", ".Image.$", "Title"); /* 是否应该为".Title" */ /* $ interpolates a string into the path expression */ // 本代码在生成IDs时有错误-- 本来应该生成在Image下却生成到了document root下了 // 在document root下建立IDs为array并设置其第0个元素为number json_setnumber(J, 116, ".IDs[0]"); /* .IDs is instantiated as an array and the number 116 set to the * 0th index */ // 经过数组索引插值方式设置IDs的第1个元素值为number json_setnumber(J, 943, ".IDs[#]", json_count(J, ".IDs")); /* As an array index, # is taken as the index value. json_count * returns the array size of .IDs as an int, which should be 1. * * (In an object key identifier, # interpolates an integer into the * string key.) */ // 将root定位在.Image.IDs[2]上 // 设置IDs[2] 的值为number // 切回document root // 设置IDs[3] 的值为number json_push(J, ".IDs[#]", json_count(J, ".IDs")); json_setnumber(J, 234, "."); json_pop(J); json_setnumber(J, 38793, ".IDs[3]"); json_printfile(J, stdout, JSON_F_PRETTY); /* The JSON_F_PRETTY flag instructs the composer to print one value * per line, and to indent each line with tabs according to its * nested level */ json_close(J); return 0; }
正如我在注释中指出的,该示例程序其实有一点小错误,本来应该输出代码最上面给出的 json 数据的,但实际输出的以下: html
[root@Betty examples]# ./example1 { "IDs" : [ 116, 943, 234, 38793 ], "Image" : { "Height" : 600, "Thumbnail" : { "Height" : 125, "Url" : "http:\/\/www.example.com\/image\/481989943", "Width" : "100" }, "Title" : "View from 15th Floor", "Width" : 800 } } [root@Betty examples]#
若想生成正确的结果,能够作以下修正: node
#include "json.h" int main(void) { struct json *J; int error; J = json_open(JSON_F_NONE, &error); json_push(J, ".Image.Thumbnail"); /* automatically instantiates . as an object, .Image as an object, * and .Image.Thumbnail as a null value. .Image.Thumbnail is now the * root node for path expressions. */ json_setstring(J, "http://www.example.com/image/481989943", ".Url"); /* automatically converts .Image.Thumbnail to an object and * instantiates .Image.Thumbnail.Url to a string */ json_setnumber(J, 125, ".Height"); json_setstring(J, "100", ".Width"); json_pop(J); /* Our root node for path expressions is again the document root */ json_setnumber(J, 800, ".Image.Width"); json_setnumber(J, 600, ".Image.Height"); json_setstring(J, "View from 15th Floor", ".Image.$", "Title"); /* $ interpolates a string into the path expression */ json_push(J,".Image"); json_setnumber(J, 116, ".IDs[0]"); /* .IDs is instantiated as an array and the number 116 set to the * 0th index */ json_setnumber(J, 943, ".IDs[#]", json_count(J, ".IDs")); /* As an array index, # is taken as the index value. json_count * returns the array size of .IDs as an int, which should be 1. * * (In an object key identifier, # interpolates an integer into the * string key.) */ json_setnumber(J, 234, ".IDs[2]"); json_setnumber(J, 38793, ".IDs[3]"); json_printfile(J, stdout, JSON_F_PRETTY); /* The JSON_F_PRETTY flag instructs the composer to print one value * per line, and to indent each line with tabs according to its * nested level */ json_close(J); return 0; }
此时的输出结果为: shell
[root@Betty examples]# ./example1 { "Image" : { "Height" : 600, "IDs" : [ 116, 943, 234, 38793 ], "Thumbnail" : { "Height" : 125, "Url" : "http:\/\/www.example.com\/image\/481989943", "Width" : "100" }, "Title" : "View from 15th Floor", "Width" : 800 } } [root@Betty examples]#
这回彻底正确了,V5!! express
另外,还有一个名字 splice 的测试小程序,其实现了将标准输入或者文件做为数据源,进行信息提取后展示到标准输出的功能。这里再也不进行源码解读,给出运行结果供参考。[root@Betty examples]# cat json_test.txt { "Image" : { "Height" : 600, "IDs" : [ 116, 943, 234, 38793 ], "Thumbnail" : { "Height" : 125, "Url" : "http:\/\/www.example.com\/image\/481989943", "Width" : "100" }, "Title" : "View from 15th Floor", "Width" : 800 } } [root@Betty examples]# [root@Betty examples]# ./splice -h splice [-Vh] to-file to-path from-file [from-path] -V print version -h print usage Report bugs to <william@25thandClement.com> [root@Betty examples]# [root@Betty examples]# ./splice json_test_2.txt . json_test.txt { "Image" : { "Height" : 600, "IDs" : [ 116, 943, 234, 38793 ], "Thumbnail" : { "Height" : 125, "Url" : "http:\/\/www.example.com\/image\/481989943", "Width" : "100" }, "Title" : "View from 15th Floor", "Width" : 800 } } [root@Betty examples]# [root@Betty examples]# ./splice json_test_2.txt . json_test.txt Image { "Height" : 600, "IDs" : [ 116, 943, 234, 38793 ], "Thumbnail" : { "Height" : 125, "Url" : "http:\/\/www.example.com\/image\/481989943", "Width" : "100" }, "Title" : "View from 15th Floor", "Width" : 800 } [root@Betty examples]# [root@Betty examples]# ./splice json_test_2.txt moooofly json_test.txt Image { "moooofly" : { "Height" : 600, "IDs" : [ 116, 943, 234, 38793 ], "Thumbnail" : { "Height" : 125, "Url" : "http:\/\/www.example.com\/image\/481989943", "Width" : "100" }, "Title" : "View from 15th Floor", "Width" : 800 } } [root@Betty examples]# [root@Betty examples]# ./splice json_test_2.txt moooofly json_test.txt Title { "moooofly" : null } [root@Betty examples]#