如何在嵌入式系统上用jsmn解析一个小JSON文件?
我需要在嵌入式系统上解析一个小JSON文件(仅10K RAM/flash)。JSON是:如何在嵌入式系统上用jsmn解析一个小JSON文件?,json,embedded,jsonparser,jsmn,Json,Embedded,Jsonparser,Jsmn,我需要在嵌入式系统上解析一个小JSON文件(仅10K RAM/flash)。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] ]} 看起来很适合这个需求,但它不像大多数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]
]}
看起来很适合这个需求,但它不像大多数JSON解析器,因为它只提供令牌。我试过了,但没能弄明白
有人可以分享一个如何用jsmn解析它的例子吗?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);
有了它,您应该能够了解如何迭代数据。您可以使用。它给你的不仅仅是代币。我用过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 );
}
}
我对此也很好奇,所以我制作了一个小程序来显示令牌数组的结构: 该计划:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "jsmn.h"
jsmntok_t t[512];
char jsonStr[512*1024];
int main()
{
size_t pos = 0;
int c;
while ((c = getchar()) != EOF)
{
jsonStr[pos] = c;
++pos;
if (pos == sizeof(jsonStr)) break;
}
jsonStr[pos] = 0;
jsmn_parser p;
jsmn_init(&p);
int tCount = jsmn_parse(&p, jsonStr, strlen(jsonStr), t, sizeof(t)/sizeof(*t));
for (int i = 0; i != tCount; ++i)
{
jsmntok_t *token = t + i;
char * type = 0;
switch (token->type)
{
case JSMN_PRIMITIVE:
type = "PRIMITIVE";
break;
case JSMN_OBJECT:
type = "OBJECT";
break;
case JSMN_ARRAY:
type = "ARRAY";
break;
case JSMN_STRING:
type = "STRING";
break;
default:
type = "UNDEF";
}
#ifdef JSMN_PARENT_LINKS
printf("node: %4d, %9s, parent: %4d, children: %5d, data:\n%.*s, \n", i, type, token->parent, token->size, token->end-token->start, jsonStr+token->start);
#else
printf("node: %4d, %9s, children: %5d, data:\n%.*s, \n", i, type, token->size, token->end-token->start, jsonStr+token->start);
#endif
}
}
作为:
我刚刚创建了jsmnRipper。此代码允许您以非常简单的方式提取用jsmn解析的令牌 这里的示例是解析ACRCloud返回的JSON消息的结果
- metadata.music[1]。分数:100:
- metadata.music[1]。唱片集。名称:最佳Depeche模式第1卷:
- metadata.music[1]。艺术家[0]。名称:Depeche模式:
- 元数据.音乐[1].标题:享受沉默(重拍版)(原件):
你可以在上找到这样做的代码,如果用了6Kb来解析它,我会大吃一惊!您确定这不是整个目标代码库的大小,而是最终链接应用程序的二进制占用空间吗?感谢您的应用,H2CO3。我是jsmn新手,如果可以的话,你能分享你的代码来解析它吗?jsmn是一个不同寻常的解析器;它的理念就在这里——“大多数JSON解析器为您提供了一系列函数来加载JSON数据、解析它并根据它的名称提取任何值。[jsmn不这样做]。”此外,它对极简主义的强调延伸到了它的文档中。如果我错了,请原谅我,by should not
tokens[1]
betokens[1]
(如果这是它最初的名称)。此外,我无法使用*key
编译第二部分,必须使其仅为key
?Thx againThanks@SSHThis--这就是我直接编码到答案框中的结果。我将使用您的修复程序进行更新。我如何知道解析了多少令牌?或者我如何迭代结果并知道我已经到达了终点?@hippietrail It应该是第一个标记的“大小”,因为所有其他标记都是它的子标记。@hippietrail如果jsmn_解析成功,它将返回解析的标记数。@NTMS这是完整代码(不包括jsmn本身).Syntax应符合c99或c11。json从标准输入读取,结果输出到标准输出。类似于gcc--std=gnu11 main.c jsmn.c&&cat my.json | a.out
的功能应该可以实现。
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
},
{
"type": "mobile",
"number": "123 456-7890"
}
],
"children": [],
"spouse": null
}
node: 0, OBJECT, parent: -1, children: 8, data:
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 25,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
},
{
"type": "mobile",
"number": "123 456-7890"
}
],
"children": [],
"spouse": null
},
node: 1, STRING, parent: 0, children: 1, data:
firstName,
node: 2, STRING, parent: 1, children: 0, data:
John,
node: 3, STRING, parent: 0, children: 1, data:
lastName,
node: 4, STRING, parent: 3, children: 0, data:
Smith,
node: 5, STRING, parent: 0, children: 1, data:
isAlive,
node: 6, PRIMITIVE, parent: 5, children: 0, data:
true,
node: 7, STRING, parent: 0, children: 1, data:
age,
node: 8, PRIMITIVE, parent: 7, children: 0, data:
25,
node: 9, STRING, parent: 0, children: 1, data:
address,
node: 10, OBJECT, parent: 9, children: 4, data:
{
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
node: 11, STRING, parent: 10, children: 1, data:
streetAddress,
node: 12, STRING, parent: 11, children: 0, data:
21 2nd Street,
node: 13, STRING, parent: 10, children: 1, data:
city,
node: 14, STRING, parent: 13, children: 0, data:
New York,
node: 15, STRING, parent: 10, children: 1, data:
state,
node: 16, STRING, parent: 15, children: 0, data:
NY,
node: 17, STRING, parent: 10, children: 1, data:
postalCode,
node: 18, STRING, parent: 17, children: 0, data:
10021-3100,
node: 19, STRING, parent: 0, children: 1, data:
phoneNumbers,
node: 20, ARRAY, parent: 19, children: 3, data:
[
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
},
{
"type": "mobile",
"number": "123 456-7890"
}
],
node: 21, OBJECT, parent: 20, children: 2, data:
{
"type": "home",
"number": "212 555-1234"
},
node: 22, STRING, parent: 21, children: 1, data:
type,
node: 23, STRING, parent: 22, children: 0, data:
home,
node: 24, STRING, parent: 21, children: 1, data:
number,
node: 25, STRING, parent: 24, children: 0, data:
212 555-1234,
node: 26, OBJECT, parent: 20, children: 2, data:
{
"type": "office",
"number": "646 555-4567"
},
node: 27, STRING, parent: 26, children: 1, data:
type,
node: 28, STRING, parent: 27, children: 0, data:
office,
node: 29, STRING, parent: 26, children: 1, data:
number,
node: 30, STRING, parent: 29, children: 0, data:
646 555-4567,
node: 31, OBJECT, parent: 20, children: 2, data:
{
"type": "mobile",
"number": "123 456-7890"
},
node: 32, STRING, parent: 31, children: 1, data:
type,
node: 33, STRING, parent: 32, children: 0, data:
mobile,
node: 34, STRING, parent: 31, children: 1, data:
number,
node: 35, STRING, parent: 34, children: 0, data:
123 456-7890,
node: 36, STRING, parent: 0, children: 1, data:
children,
node: 37, ARRAY, parent: 36, children: 0, data:
[],
node: 38, STRING, parent: 0, children: 1, data:
spouse,
node: 39, PRIMITIVE, parent: 38, children: 0, data:
null,