【问题标题】:Parse JSON and JSON values with jq使用 jq 解析 JSON 和 JSON 值
【发布时间】:2018-09-01 10:50:44
【问题描述】:

我有一个返回 JSON 的 API - 它的大块。一些键值对具有更多的 JSON 块作为与键关联的值。 jq 在解析主要 JSON 级别方面做得很好。但是我找不到一种方法让它“递归”到与键关联的值并漂亮地打印它们。

这是其中一个 JSON 返回的开始。请注意,这只是全部回报的一小部分:

    {
  "code": 200,
  "status": "OK",
  "data": {
    "PlayFabId": "xxxxxxx",
    "InfoResultPayload": {
      "AccountInfo": {
        "PlayFabId": "xxxxxxxx",
        "Created": "2018-03-22T19:23:29.018Z",
        "TitleInfo": {
          "Origination": "IOS",
          "Created": "2018-03-22T19:23:29.033Z",
          "LastLogin": "2018-03-22T19:23:29.033Z",
          "FirstLogin": "2018-03-22T19:23:29.033Z",
          "isBanned": false
        },
        "PrivateInfo": {},
        "IosDeviceInfo": {
          "IosDeviceId": "xxxxxxxxx"
        }
      },
      "UserVirtualCurrency": {
        "GT": 10,
        "MB": 70
      },
      "UserVirtualCurrencyRechargeTimes": {},
      "UserData": {},
      "UserDataVersion": 15,
      "UserReadOnlyData": {
        "DataVersion": {
          "Value": "6",
          "LastUpdated": "2018-03-22T19:48:59.543Z",
          "Permission": "Public"
        },
        "achievements": {
          "Value": "[{\"id\":0,\"gamePack\":\"GAME.PACK.0.KK\",\"marblesAmount\":50,\"achievements\":[{\"id\":2,\"name\":\"Correct Round 4\",\"description\":\"Round 4 answered correctly\",\"maxValue\":10,\"increment\":1,\"currentValue\":3,\"valueUnit\":\"unit\",\"awardOnIncrement\":true,\"marbles\":10,\"image\":\"https://www.jamandcandy.com/kissinkuzzins/achievements/icons/sphinx\",\"SuccessKey\":[\"0_3_4_0\",\"0_5_4_0\",\"0_6_4_0\",\"0_7_4_0\",\"0_8_4_0\",\"0_9_4_0\",\"0_10_4_0\"],\"event\":\"Player_answered_round\",\"achieved\":false},{\"id\":0,\"name\":\"Complete

这是使用 jq 解析的,但是当您到达时可以看到

"achievements": { "Vales": "[{\"id\":0,\"gamePack\":\"GAME.PACK.0.KK\",\"marblesAmount\":50,\

lq 没有进一步解析值也是 JSON。

我是否缺少过滤器来解析值以及更高级别的结构?

【问题讨论】:

  • 请确保您的样品是完整的,例如主要示例应该是有效的 JSON,并且在 sn-p 中,“成就”的值应该是有效的 JSON。
  • Value 不会映射到更结构化的 JSON。它映射到单个字符串,该字符串恰好包含转义并存储为字符串的 JSON。任何有效的 JSON 解析器都不会进一步解析该值;转义显式存在以防止解析器尝试这样做,至少在该字符串上显式调用它之前。如果您的任何代码正在生成此 JSON,那么它的做法是错误的。

标签: json recursion jq fromjson


【解决方案1】:

我是否缺少过滤器...?

您需要的过滤器是fromjson,但它应该只应用于字符串化的 JSON;因此考虑使用|=,如使用您的片段所示:

echo '{"achievements": { "Vales": "[{\"id\":0,\"gamePack\":\"GAME.PACK.0.KK\",\"marblesAmount\":50}]"}}' | 
  jq '.achievements.Vales |= fromjson'

{
  "achievements": {
    "Vales": [
      {
        "id": 0,
        "gamePack": "GAME.PACK.0.KK",
        "marblesAmount": 50
      }
    ]
  }
}

递归/1

如果您想尽可能递归地应用fromjson,那么recursively 是您的朋友:

def recursively(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key]  | recursively(f) )} )
  elif type == "array" then map( recursively(f) )
  else try (f as $f | if $f == . then . else ($f | recursively(f)) end) catch $in
  end;

这将应用如下:

recursively(fromjson)

示例

{a: ({b: "xyzzy"}) | tojson} | tojson 
| recursively(fromjson)

产量:

{
  "a": {
    "b": "xyzzy"
  }
}

【讨论】:

  • 超级这个递归到值是我想要做的。我会看看我能用这些想法把什么放在一起。我意识到就封闭的 JSON 而言,它是一个字符串。我仍然想要一种方法来递归到它并解析它——即使它被转义了。这似乎是尝试的正确方向。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多