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]#