如何解析 duktape 中的递归 json 数据?
How to parse recursive json data in duktape?
我正在尝试使用 duktape 解析递归数据结构,但似乎某处有错误。
由于我是duktape库的新手,而且这种情况下的例子不清楚,我想我可以问问人群。
数据:
{
"type": "window",
"children": [
{
"type": "button"
},
{
"type": "button"
}
]
}
使用解析它的函数:
void parse_config() {
duk_context* context = duk_create_heap_default();
std::cout << "duk_create_heap_default" << std::endl;
duk_push_string(context, input.c_str());
std::cout << "duk_push_string" << std::endl;
duk_json_decode(context, 0);
std::cout << "duk_json_decode" << std::endl;
parse_widget(context);
}
void parse_widget(duk_context* context) {
duk_get_prop_string(context, 0, "type");
std::cout << "duk_get_prop_string" << std::endl;
auto type = duk_get_string(context, 1);
std::cout << "duk_get_string" << std::endl;
duk_pop(context);
std::cout << "duk_pop" << std::endl;
std::cout << "type: " << type << std::endl;
if (duk_has_prop_string(context, 0, "children")) {
std::cout << "duk_has_prop_string" << std::endl;
parse_children(context);
} else {
std::cout << "duk_has_prop_string" << std::endl;
std::cout << "no children" << std::endl;
}
}
void parse_children(duk_context* context) {
duk_get_prop_string(context, 0, "children");
std::cout << "duk_get_prop_string" << std::endl;
if (duk_is_array(context, 1)) {
std::cout << "duk_is_array" << std::endl;
duk_enum(context, 1, 0);
std::cout << "duk_enum" << std::endl;
while (duk_next(context, 2, 0)) {
std::cout << "duk_next" << std::endl;
std::cout << "parse child" << std::endl;
parse_widget(context);
}
}
}
使用这个版本我得到输出:
$ ./programm
duk_create_heap_default
duk_push_string
duk_json_decode
duk_get_prop_string
duk_get_string
duk_pop
type: window
duk_has_prop_string
duk_get_prop_string
duk_is_array
duk_enum
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: $
正确的输出当然应该是:
duk_create_heap_default
duk_push_string
duk_json_decode
duk_get_prop_string
duk_get_string
duk_pop
type: window
duk_has_prop_string
duk_get_prop_string
duk_is_array
duk_enum
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: button
duk_has_prop_string
no children
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: button
duk_has_prop_string
no children
所以问题仍然存在:我解析数据的错误在哪里?
我可以看到两个问题:
您在 parse_widget/parse_children 中使用值堆栈索引 0 和 1,一旦您递归,这将是不正确的。请注意,当您执行正常的 C 函数调用时,堆栈索引 0 不会更改(但当您使用 duk_call()
调用 native/Ecmascript 函数时会更改)。您应该使用负索引来引用相对于堆栈顶部的项目;您也可以使用非负索引,但跟踪当前正在处理的小部件的基本索引。
子数组以及 duk_next()
循环中的枚举键和值缺少 duk_pop()
。
我正在尝试使用 duktape 解析递归数据结构,但似乎某处有错误。 由于我是duktape库的新手,而且这种情况下的例子不清楚,我想我可以问问人群。
数据:
{
"type": "window",
"children": [
{
"type": "button"
},
{
"type": "button"
}
]
}
使用解析它的函数:
void parse_config() {
duk_context* context = duk_create_heap_default();
std::cout << "duk_create_heap_default" << std::endl;
duk_push_string(context, input.c_str());
std::cout << "duk_push_string" << std::endl;
duk_json_decode(context, 0);
std::cout << "duk_json_decode" << std::endl;
parse_widget(context);
}
void parse_widget(duk_context* context) {
duk_get_prop_string(context, 0, "type");
std::cout << "duk_get_prop_string" << std::endl;
auto type = duk_get_string(context, 1);
std::cout << "duk_get_string" << std::endl;
duk_pop(context);
std::cout << "duk_pop" << std::endl;
std::cout << "type: " << type << std::endl;
if (duk_has_prop_string(context, 0, "children")) {
std::cout << "duk_has_prop_string" << std::endl;
parse_children(context);
} else {
std::cout << "duk_has_prop_string" << std::endl;
std::cout << "no children" << std::endl;
}
}
void parse_children(duk_context* context) {
duk_get_prop_string(context, 0, "children");
std::cout << "duk_get_prop_string" << std::endl;
if (duk_is_array(context, 1)) {
std::cout << "duk_is_array" << std::endl;
duk_enum(context, 1, 0);
std::cout << "duk_enum" << std::endl;
while (duk_next(context, 2, 0)) {
std::cout << "duk_next" << std::endl;
std::cout << "parse child" << std::endl;
parse_widget(context);
}
}
}
使用这个版本我得到输出:
$ ./programm
duk_create_heap_default
duk_push_string
duk_json_decode
duk_get_prop_string
duk_get_string
duk_pop
type: window
duk_has_prop_string
duk_get_prop_string
duk_is_array
duk_enum
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: $
正确的输出当然应该是:
duk_create_heap_default
duk_push_string
duk_json_decode
duk_get_prop_string
duk_get_string
duk_pop
type: window
duk_has_prop_string
duk_get_prop_string
duk_is_array
duk_enum
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: button
duk_has_prop_string
no children
duk_next
parse child
duk_get_prop_string
duk_get_string
duk_pop
type: button
duk_has_prop_string
no children
所以问题仍然存在:我解析数据的错误在哪里?
我可以看到两个问题:
您在 parse_widget/parse_children 中使用值堆栈索引 0 和 1,一旦您递归,这将是不正确的。请注意,当您执行正常的 C 函数调用时,堆栈索引 0 不会更改(但当您使用
duk_call()
调用 native/Ecmascript 函数时会更改)。您应该使用负索引来引用相对于堆栈顶部的项目;您也可以使用非负索引,但跟踪当前正在处理的小部件的基本索引。子数组以及
duk_next()
循环中的枚举键和值缺少duk_pop()
。