2013-05-23 3 views
2

У меня есть YAJL, анализирующий простые элементы, подобные приведенным в прилагаемом примере, без проблем. (Строки, целые числа, массивы, ...)Parse complex JSON sub objects in C with YAJL

Пример кода можно найти здесь: http://lloyd.github.io/yajl/yajl-2.0.1/example_2parse_config_8c-example.html

, но теперь у меня есть этот тип объекта JSON:

{ 
"cmd":2, 
"properties": 
    [ 
     { 
     "idx":40, 
     "val":8813.602692 
     }, 
     { 
     "idx":41, 
     "val":960 
     }, 
     { 
     "idx":42, 
     "val":2 
     }, 
     { 
     "idx":48, 
     "val":9 
     } 
    ] 

}

Я могу получить команду с помощью (см. Определения используемых переменных в связанном примере):

const char * path[] = {"cmd", (const char *) 0 }; 
yajl_val v = yajl_tree_get(ynode, path, yajl_t_number); 
if (v) 
    *cmd = (commands)((int)YAJL_GET_INTEGER(v)); 

И я могу получить ссылку на массив свойств с помощью:

int ar_sz; 
const char * path[] = {"properties", (const char *) 0 }; 
yajl_val v = yajl_tree_get(ynode, path, yajl_t_array); 
if (v) 
    { 
    ar_sz = v->u.array.len; 
    } 

Это дает мне правильный размер массива, но я понятия не имею, о том, как получить вложенные элементы IDX и Вэл из элементов массива.

Любая помощь очень ценится

ответ

4

Глядя на yajl_tree.h конкретно yajl_val_s структуры:

{ 
    const char * path[] = { "properties", (const char *) 0 }; 
    yajl_val v = yajl_tree_get(node, path, yajl_t_array); 
    if (v && YAJL_IS_ARRAY(v)) { 
     printf("is array\n"); 

     // iterate over array elements, 
     // it's an array so access array.len inside yajl_val_s.union 
     size_t len = v->u.array.len; 
     int i; 
     for (i = 0; i < len; ++i) { 

      // get ref to one object in array at a time 
      yajl_val obj = v->u.array.values[ i ]; // object 
      // iterate over values in object: pairs of (key,value) 
      // u.object.len tells you number of elements 
      size_t nelem = obj->u.object.len; 
      int ii; 
      for (ii = 0; ii < nelem; ++ii) { 
       // key is just char * 
       const char * key = obj->u.object.keys[ ii ];  // key 
       // values is an array object 
       yajl_val val = obj->u.object.values[ ii ];  // val 
       // example: check if double, 
       // could do more checks or switch on value ... 
       if (YAJL_IS_DOUBLE(val)) 
        printf("%s/%f ", key, val->u.number.d); 
      } 
      printf("\n"); 
     } 
    } else { printf("is not array\n"); } 
} 

Выход должен быть что-то вроде:

is array 
idx/40.000000 val/8813.602692 
idx/41.000000 val/960.000000 
idx/42.000000 val/2.000000 
idx/48.000000 val/9.000000