5

我正在处理操纵“宽松”JSON 数据的系统,其中包括 shell 样式的#行注释:

[
  {
    # Batman
    "first-name": "Bruce",
    "last-name": "Wayne"
  },
  {
    # Superman
    "first-name": "Clark",
    "last-name": "Kent"
  }
]

我正在处理的系统部分使用json-lib(我惊讶地发现它可以容忍 shell 样式的注释)来解析 JSON 输入。

我需要从这些注释中提取一些额外的注释,但 json-lib 似乎只是丢弃它们而不提供用于读取它们的 API:

JSONObject map = (JSONObject)JSONSerializer.toJSON("{\n"+
                                                   "    # Batman\n" + // note the shell-style # comment
                                                   "    \"first-name\": \"Bruce\",\n" +
                                                   "    \"last-name\": \"Wayne\"\n" +
                                                   "}");
System.out.println(map.toString());
/* <<'OUTPUT'
 * {"first-name":"Bruce","last-name":"Wayne"}
 * OUTPUT
 * note the absence of the shell-style comment
 */

这是有道理的,因为注释不是 JSON 规范的一部分,而且我很幸运 json-lib 在解析它们时不只是窒息。

注意:

  • 其他系统使用相同的 JSON,并且注释需要对它们透明,因此不能通过添加注释属性来修改 JSON 结构。
  • 并非我系统中的所有组件和对象都可以访问原始 JSON 源:一个组件读取文件并使用 JSONlib 解析它并传递反序列化的映射等。

在处理 JSON 输入时如何阅读和解析这些注释?是否有一个库可以让我阅读它们并将它们与它们在 JSON 中的位置相关联 - 我可以轻松地将Batman评论连接到“布鲁斯韦恩”条目吗?

我目前正在使用 json-lib,但我愿意研究其他 JSON 库,并且同样愿意使用其他扩展 JSON 的语言,例如 YAML - 但我不确定这些工具是否允许我阅读和处理我输入的评论。

4

2 回答 2

4

编辑(2021 年 5 月 27 日):

我选择为这个非标准版本的 JSON 编写自定义 JSON 解析器。它支持您问题中给出的 shell 注释,但仅在 JSON 对象的第一个键之前:

(前面是用 C# 编写的;预计还会提供 Java 版本。它依赖于我的简洁二进制对象表示库,在 NuGet 中称为 PeterO.Cbor 或在中央存储库中称为 com.upokecenter/cbor。)

实际上,您的要求之一是“不能通过添加注释属性来修改 JSON 结构”。这意味着评论必须以其他方式与 JSON 对象相关联。幸运的是,最近发布了一个名为 JSON Pointer 的规范作为 RFC 6901。JSON Pointer 是一个字符串,它引用另一个 JSON 对象中的 JSON 对象。这就是为什么解析器包含一种通过名为JSONWithComments.FromJSONStringWithPointers. JSONPointer.cs是我自己实现的 JSON 指针规范。

使用示例:

      dict=new Dictionary<string, string>();
      str="{\"f\":[\n {\n # B\t \tA C\n # Dm\n\"a\":1,\n\"b\":2\n},{\n #" +
"\u0020Sm\n\"a\":3,\n\"b\":4\n}\n]}";
       obj = JSONWithComments.FromJSONString(str);
      Console.WriteLine(obj);
       obj = JSONWithComments.FromJSONStringWithPointers(str, dict);
       // Get the comment and its associated JSON pointer
       foreach(string key in dict.Keys) {
         Console.WriteLine(key);
         Console.WriteLine(dict[key]);
         // Get the pointed-to object
         Console.WriteLine(JSONPointer.GetObject(obj,dict[key]));
       }
       // Output the object
      Console.WriteLine(obj);
于 2013-05-07T00:53:06.677 回答
0

其他系统使用相同的 JSON 并且注释需要对它们透明,因此不能通过添加注释属性来修改 JSON 结构

在消息中使用注释在系统之间传递数据似乎不是一个好习惯。. 例如,XML 不支持这一点。

为什么不简单地将重要的“评论”合并为数据?如果其他系统正在使用它,那就是它。:^)

于 2013-05-08T06:18:25.880 回答