如何在 powershell 中比较 JSON

How to compare JSON in powershell

我有一个要求,我需要将文件中的 JSON 对象与进入 Anypoint MQ 队列的 JSON 消息进行比较。我能够从队列中获取消息。我使用了下面的脚本,但它不起作用。 -eqCompare-Object 我都做了,但它们不起作用。

$po_ps_output = $filemessagecontent | ConvertFrom-Json
$po_python_output = $mqmessagecontent.body | ConvertFrom-Json
$result = $po_ps_output -eq $po_python_output

如果你只是想知道如果两个JSON-起源的对象不同,而不需要知道如何:

$contentEqual = ($po_ps_output | ConvertTo-Json -Compress) -eq 
                ($po_python_output | ConvertTo-Json -Compress)

注:

  • ConvertTo-Json 默认序列化深度为 2 - 如果您的数据嵌套更深以避免截断(潜在的数据丢失),请使用 -Depth <n> - 请参阅.

  • 转换回 JSON 似乎是一个不必要的步骤,但是 -Compress 将输出格式标准化为单行,没有额外的空格,这确保了偶然的变化输入中的格式设置(如果您直接使用输入 JSON 文本)将被忽略。


如果你想知道如何这两个JSON-起源的对象不同:

注意:以下是仅在以下有限场景中有用- 一个通用的、强大的解决方案将需要更多的努力:

  • 输入具有 相同的结构,仅在 属性 个名称/值上有所不同。

  • (等效)属性的排序相同。

Compare-Object (($po_ps_output | ConvertTo-Json) -split '\r?\n') `
               (($po_python_output | ConvertTo-Json) -split '\r?\n')

输出将显示不同的行,每行代表一个 属性 或原始值;例如:

InputObject                   SideIndicator
-----------                   -------------
      "DOB":  "12-03-1994"    =>
      "DOB":  "12-03-1999"    <=

注:

  • => / <=表示该行是RHS/LHS唯一的。

  • 再次明确转换为JSON以确保格式统一;在这种情况下,一种面向行的漂亮打印格式,支持 属性-by-属性 比较。

  • 同样,您可能必须使用 -Depth 来防止数据被截断。

  • 为了interactive检查差异,你可以尝试差异可视化工具,比如内置在Visual Studio代码中的工具,通过传递通过文件到
    code --diff <file1> <file2>.

  • 的两个 JSON 字符串

至于你试过的

ConvertFrom-Json 创建 [pscustomobject] 个实例,因此您正在比较该类型的两个实例:

  • 如果使用-eqreference equality会被测试,因为[pscustomobject]是一个引用类型,并没有实现自定义相等比较。

    • 因此,如果两个变量指向内存中的非常相同的对象,则$po_ps_output -eq $po_python_output只会是$true——这里显然不是这种情况,所以你总是会得到 $false
  • 如果您使用 Compare-Object,则两个实例将根据它们的 .ToString() 值进行比较。

    • 从 PowerShell Core 7.0.0-preview.4 开始,遗憾的是,在 [pscustomobject] 的实例上调用 .ToString() 会产生 空字符串 (''),这应该被视为一个错误 - 请参阅 this GitHub issue.

    • 因此,Compare-Object $po_ps_output $po_python_output(毫无帮助)认为两个实例 等于 和 returns 什么都没有,因为默认情况下相等的对象不是输出(使用 -IncludeEqual 来包含它们)。