json 输出数组中出现意外的空元素

svmlkihl  于 2022-11-19  发布在  其他
关注(0)|答案(3)|浏览(174)

编辑:现在经过16个小时的休息,我意识到我已经误读了几个小时的结果-我没有注意到在所有情况下都有null,所以行为是一致的,不像我在这个问题中声称的那样(捂脸)。但是,我决定不删除这个问题,而只是关闭它,因为已经有有用的答案。

考虑以下输入JSON:

{
  "widgets": [
    {
      "type": "FOO",
      "id": "F1"
    },
    {
      "type": "ZAP",
      "id": "Z1"
    },
    {
      "type": "BAR",
      "id": "B1"
    }
  ]
}

以下转换:

[
  {
    "operation": "shift",
    "spec": {
      "widgets": {
        "*": {
          "type": {
            "FOO": {
              "@(2,id)": "widgets[&3].fooId"
            },
            "BAR": {
              "@(2,id)": "widgets[&3].barId"
            }
          }
        }
      }
    }
  }
]

创建预期的(正确的)输出。编辑我误读了此输出-我没有意识到有3个元素其中一个元素为空,但我认为只有2个非空元素

{
  "widgets": [
    {
      "fooId": "F1"
    },
    null,
    {
      "barId": "B1"
    }
  ]
}

但是,以下转换会创建意外的输出:

[
  {
    "operation": "shift",
    "spec": {
      "widgets": {
        "*": {
          "type": {
            "BAR": {
              "@(2,id)": "widgets[&3].barId"
            }
          }
        }
      }
    }
  }
]

这是实际(错误)输出:

{
  "widgets": [
    null,
    null,
    {
      "barId": "B1"
    }
  ]
}

以下是预期(正确)输出:

{
  "widgets": [
    {
      "barId": "B1"
    }
  ]
}

为什么widgets数组中有时有null元素,有时没有?如何避免?
基于许多其他SO问题进行以下操作:

{
  "operation": "modify-overwrite-beta",
  "spec": {
    "*": "=recursivelySquashNulls"
  }
}

应该删除null值,但为什么在下面的转换中没有删除这些值?

[
  {
    "operation": "shift",
    "spec": {
      "widgets": {
        "*": {
          "type": {
            "BAR": {
              "@(2,id)": "widgets[&3].barId"
            }
          }
        }
      }
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "*": "=recursivelySquashNulls"
    }
  }
]

我在http://jolt-demo.appspot.com/中观察到这种行为

h9vpoimq

h9vpoimq1#

第一个输出也保留了null(我不知道它是否应该出现在所需的输出中)。由于具有"type": "ZAP"的对象的索引(1)位于索引(012)的中间,而不是末尾,因此不会在该级别消失。
顺便说一句,squashNulls尤其对数组中的嵌套对象没有影响。事实上,它有一些bug,并被记录为version 0.1.6的修复。
您可以使用以下没有方括号索引的规范,例如

[
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": {
          "type": {
            "FOO|BAR": {
              "@(2,id)": "&4.&1.&1Id"
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "*": {
        "*": {
          "@": "&2[]"
        }
      }
    }
  }
]
ih99xse1

ih99xse12#

此规范将帮助您解决此查询:
1)的
实际上,如果你把数组保存在一个对象中,比如:我把它放在测试对象下,并使它达到前一个。
此规范将解决您的问题:

[
  {
    "operation": "shift",
    "spec": {
      "widgets": {
        "*": {
          "type": {
            "BAR": {
              "@(2,id)": "widgets[&3].barId"
            }
          }
        }
      }
    }
  }, {
    "operation": "shift",
    "spec": {
      "*": "test.&"
    }
  },
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "*": "=recursivelySquashNulls"
    }
  },
  {
    "operation": "shift",
    "spec": {
      "test": {
        "*": "&"
      }
    }
  }
]

4dc9hkyq

4dc9hkyq3#

看起来http://jolt-demo.appspot.com/中的Web应用程序运行的是旧版本0.1.1,在这种情况下,其行为与新版本略有不同。
目前,Maven Central中可用的最新版本似乎是0.1.7:

我以为Github发布页面只声明最新版本是0.1.6:

我的印象是,非常强大和有用的Jolt库并没有得到它应得的所有照顾:(
squashNull在使用版本0.1.7时在Java代码中似乎工作正常。
下面是我根据Barbaros Özhan的回答,对http://jolt-demo.appspot.com/进行的最终转换:

[
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "widgets": {
        "*": {
          "type": "=toLower"
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "widgets": {
        "*": {
          "type": {
            "foo|bar": {
              "@(2,id)": "&4.&1.&1Id"
            }
          }
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "widgets": {
        "*": {
          "@": "&2[]"
        }
      }
    }
  }
]

相关问题