使用Parson库解析Azure IoT Hub JSON时识别为字符串问题求助
问题原因分析
你的解析结果被识别为JSONString类型(类型2),核心原因有两个:
- 外层多余引号包裹:两个示例中的内容都被外层双引号包裹(示例1是
"{'device': '65'}",示例2是"{\"device\": \"3445667\"}"),Parson会把整个内容解析成一个字符串值,而非JSON对象。 - 单引号不符合JSON规范:示例1使用了单引号包裹键和值,但JSON标准(RFC 8259)要求必须用双引号,单引号无法被标准解析器识别为合法的JSON结构。
解决方案
需要先对payload_buffer中的原始字符串做清理处理,再进行解析:
1. 添加字符串清理辅助函数
// 清理原始JSON字符串:去除外层引号、替换单引号为双引号 void prepare_valid_json(char *input, char *output, size_t max_output_len) { size_t input_len = strlen(input); // 去除首尾的外层双引号 if (input_len >= 2 && input[0] == '"' && input[input_len - 1] == '"') { strncpy(output, input + 1, input_len - 2); output[input_len - 2] = '\0'; } else { strncpy(output, input, max_output_len - 1); output[max_output_len - 1] = '\0'; } // 将单引号替换为双引号,适配示例1的不规范格式 char *ptr = output; while ((ptr = strchr(ptr, '\'')) != NULL) { *ptr = '"'; ptr++; } }
2. 修改主解析代码
uint8_t payload_buffer[448]; JSON_Value *root_value = NULL; JSON_Object *root_object = NULL; JSON_Value *device_name = NULL; const char* device; char cleaned_json[448]; // 存储清理后的合法JSON printf("%.*s \r\n", (INT)insert_index, (CHAR *)&payload_buffer ); // 先清理原始字符串 prepare_valid_json((char *)payload_buffer, cleaned_json, sizeof(cleaned_json)); root_value = json_parse_string(cleaned_json); if (root_value != NULL) { if (json_value_get_type(root_value) == JSONObject) { root_object = json_value_get_object(root_value); device_name = json_object_dotget_value(root_object, "device"); device = json_value_get_string(device_name); if (device != NULL) { printf("device: %s", device ); } } else { printf("JSON Type: %u \r\n", json_value_get_type(root_value)); printf("Cleaned JSON content: %s \r\n", cleaned_json); // 打印清理后的内容用于排查 } }
额外排查建议
如果清理后仍无法解析为JSONObject,可以:
- 打印
cleaned_json的内容,确认是否符合{"device": "xxx"}的标准JSON格式 - 检查
payload_buffer中是否存在多余的换行、空格或不可见字符,可通过逐字节打印排查
内容的提问来源于stack exchange,提问作者Martin Joseph
相关产品推荐
相关产品推荐

