实现json解析工具jcat
jcat是一个shell下的解析json的工具,具有以下功能:
- 支持指定路径解析,打印指定路径下的所有对象信息
- 支持宏路径,可以级联宏替换
- 使用tbox进行了跨平台支持,预编译版本直接可以在./tbox/tool目录下找到,因为新版tbox makefile架构就是采用jcat来解析*.pkg/manifest.json清单文件
使用方式拿polarssl.pkg/manifest.json的举例:
{ "format": { "name": "The TBOOX Package Format" , "version": "v1.0.1" , "website": "http://www.tboox.org" } , "package": { "name": "The PolarSSL Library" , "website": "http://www.polarssl.org" } , "compiler": { "default": { "debug": { "libs": "polarssl" , "libpath": "" , "incpath": "" , "libflags": "" , "incflags": "" } , "release": "$.compiler.default.debug" } , "linux" : { "x64": "$.compiler.default" } , "mac" : { "x86": "$.compiler.default" , "x64": "$.compiler.default" } , "msvc" : { "x86": "$.compiler.default" } , "mingw" : { "x86": "$.compiler.default" } , "cygwin" : { "x86": "$.compiler.default" } , "ios" : { "armv7": "$.compiler.default" , "armv7s": "$.compiler.default" , "arm64": "$.compiler.default" } , "android" : { "armv5te": "$.compiler.default" , "armv6": "$.compiler.default" } } }
上述manifest.json中,以$开头的字符串均为宏路径,例如:$.compiler.default,用来引用其他地方的配置数据,减小配置冗余
执行jcat, 获取 .compiler.mac.x64.debug 路径的内容
./tool/jcat/jcat --filter=.compiler.mac.x64.debug ./pkg/polarssl.pkg/manifest.json
返回结果如下:
{"incpath":"","incflags":"","libs":"polarssl","libflags":"","libpath":""}
是不是很方便?解析过程可以递归处理替换宏路径,返回真实的数据。其他详细使用方式,可以通过如下命令获取:
./tool/jcat/jcat --help
看了使用过程,是不是觉得实现这样一个jcat很复杂呢,其实非常简单,只要使用TBOX的object库,可以非常方便的实现它,下面就晒下jcat的代码吧:
#include "tbox/tbox.h" static tb_option_item_t g_options[] = { { ‘f‘ , "filter" , TB_OPTION_MODE_KEY_VAL , TB_OPTION_TYPE_CSTR , "the json filter\n" ".e.g\n" "\n" "file:\n" "{\n" " \"string\": \"hello world!\"\n" ", \"com.xxx.xxx\": \"hello world\"\n" ", \"integer\": 31415926\n" ", \"array\":\n" " [\n" " \"hello world!\"\n" " , 31415926\n" " , 3.1415926\n" " , false\n" " , true\n" " , { \"string\": \"hello world!\" }\n" " ]\n" ", \"macro\": \"$.array[2]\"\n" ", \"macro2\": \"$.com\\\\.xxx\\\\.xxx\"\n" ", \"macro3\": \"$.macro\"\n" ", \"macro4\": \"$.array\"\n" "}\n" "\n" "filter:\n" " 1. \".string\" : hello world!\n" " 2. \".array[1]\" : 31415926\n" " 3. \".array[5].string\" : hello world!\n" " 4. \".com\\.xxx\\.xxx\" : hello world\n" " 5. \".macro\" : 3.1415926\n" " 6. \".macro2\" : hello world\n" " 7. \".macro3\" : 3.1415926\n" " 8. \".macro4[0]\" : \"hello world!\"\n" } , {‘h‘, "help", TB_OPTION_MODE_KEY, TB_OPTION_TYPE_BOOL, "display this help and exit"} , {‘-‘, "file", TB_OPTION_MODE_VAL, TB_OPTION_TYPE_CSTR, "the json file" } }; /* ////////////////////////////////////////////////////////////////////////////////////// * main */ tb_int_t main(tb_int_t argc, tb_char_t** argv) { // init tbox if (!tb_init(tb_null, tb_null, 0)) return 0; // init option tb_option_ref_t option = tb_option_init("jcat", "cat the json file", g_options); if (option) { // done option if (tb_option_done(option, argc - 1, &argv[1])) { // done file if (tb_option_find(option, "file")) { // load object tb_object_ref_t root = tb_object_read_from_url(tb_option_item_cstr(option, "file")); if (root) { // done filter tb_object_ref_t object = root; if (tb_option_find(option, "filter")) object = tb_object_seek(root, tb_option_item_cstr(option, "filter"), tb_true); // dump 数据对象,这里主要为了过滤 字符串内容的 "" // 否则直接使用tb_object_dump会更简单,只需一行代码 if (object) { // done tb_char_t info[8192] = {0}; tb_long_t size = tb_object_writ_to_data(object, (tb_byte_t*)info, sizeof(info), TB_OBJECT_FORMAT_JSON | TB_OBJECT_FORMAT_DEFLATE); if (size > 0) { // strip string: "" tb_char_t* show = info; if (info[0] == ‘\"‘ && info[size - 1] == ‘\"‘) { show++; info[size - 1] = ‘\0‘; } // trace tb_printf("%s\n", show); } } // exit object tb_object_exit(root); } } else tb_option_help(option); } else tb_option_help(option); // exit option tb_option_exit(option); } // exit tbox tb_exit(); // ok return 0; }
简单吧,就只要一百行代码,还支持详细的命令行选项支持。
附带一句:其实jcat同时还可以支持解析xml和plist哦,因为他用了object模块的多数据格式探测功能,完全可以自动解析不同格式的数据,还能方便扩展自己的数据格式。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。