如何在嵌入式系统上解析带有jsmn的小JSON文件?

时间:2013-01-17 21:44:48

标签: json embedded jsonparser jsmn

我需要在嵌入式系统上解析一个小的JSON文件(只有10K RAM /闪存)。 JSON是:

{
"data1":[1,2,3,4,5,6,7,8,9],
"data2":[
     [3,4,5,6,1],
     [8,4,5,6,1],
     [10,4,5,3,61],
     [3,4,5,6,1],
     [3,4,5,6,1],
     [3,4,5,6,1] 
]}

jsmn 看起来很符合要求,但它不像大多数JSON解析器,因为它只提供令牌。我试过了,但无法理解。

有人可以分享一个如何用jsmn解析它的例子吗?

3 个答案:

答案 0 :(得分:22)

jsmn将为您提供一组令牌,这些令牌指的是从左到右的JSON阅读中的令牌。

在你的情况下:

token[0]: (outer) object, 2 children
token[1]: string token ("data1")
token[2]: array, 9 children
token[3]: primitive token (1)
etc...

进行解析的基本代码是:

int resultCode;
jsmn_parser p;
jsmntok_t tokens[128]; // a number >= total number of tokens

jsmn_init(&p);
resultCode = jsmn_parse(&p, yourJson, tokens, 256);

另一个技巧是获取令牌的价值。令牌包含原始字符串上数据的起点和终点。

jsmntok_t key = tokens[1];
unsigned int length = key.end - key.start;
char keyString[length + 1];    
memcpy(keyString, &yourJson[key.start], length);
keyString[length] = '\0';
printf("Key: %s\n", keyString);

有了这个,您应该能够找到如何迭代数据的方法。

答案 1 :(得分:0)

您可以使用tiny-json。它给你的不仅仅是令牌。我使用了16位和32位的微控制器,它工作正常。

char str[] = "{"
                 "\"data1\":[1,2,3,4,5,6,7,8,9],"
                 "\"data2\":["
                     "[3,4,5,6,1],"
                     "[8,4,5,6,1],"
                     "[10,4,5,3,61],"
                     "[3,4,5,6,1],"
                     "[3,4,5,6,1],"
                     "[3,4,5,6,1]"
                 "]"
             "}";
puts( str );

json_t pool[64];
json_t const* root = json_create( str, pool, 64 );

json_t const* data1 = json_getProperty( root, "data1" );
if ( data1 && JSON_ARRAY == json_getType( data1 ) ) {

    json_t const* field = json_getChild( data1 );
    while( field ) {

        if ( JSON_INTEGER == json_getType( field ) ) {
            long long int data = json_getInteger( field );
            printf("Integer from data1: %lld\n", data );
        }

        field = json_getSibling( field );
    }
}

json_t const* data2 = json_getProperty( root, "data2" );
if ( data2 && JSON_ARRAY == json_getType( data2 ) ) {

    json_t const* array = json_getChild( data2 );
    while( array ) {

        if ( JSON_ARRAY == json_getType( array ) ) {
            puts("Array in data2");

            json_t const* field = json_getChild( array );
            while( field ) {

                if ( JSON_INTEGER == json_getType( field ) ) {
                    long long int data = json_getInteger( field );
                    printf("Integer from array of data2: %lld\n", data );
                }

                field = json_getSibling( field ); 
            }
        }
        array = json_getSibling( array );
    }
} 

答案 2 :(得分:0)

我刚创建了jsmnRipper。此代码允许您以非常简单的方式提取使用jsmn解析的标记。

这里的示例是解析ACRCloud返回的JSON消息的结果

  • metadata.music [1] .score:100:
  • metadata.music [1] .album.name:最佳模式第1卷:
  • metadata.music [1] .artists [0] .name:Depeche Mode:
  • metadata.music [1] .title:Enjoy The Silence(Remastered Version)(原创):

您可以在https://github.com/ipserc/jsmnRipper

找到执行该操作的代码