Как сравнить JSON в powershell - PullRequest
1 голос
/ 01 октября 2019

У меня есть требование, где мне нужно сравнить объект JSON из файла с сообщением JSON, которое поступает в очередь Anypoint MQ. Я могу получить сообщение из очереди. Я использовал скрипт ниже, но он не работает. Я сделал оба -eq и Compare-Object, но они не работают.

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

1 Ответ

1 голос
/ 01 октября 2019

Если вы просто хотите узнать , если , два объекта, созданные в JSON, отличаются , без необходимости знать как :

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

Примечание:

  • ConvertTo-Json по умолчанию имеет глубину сериализации 2 - используйте -Depth <n>, если ваши данные более глубоко вложены, чтобы избежать усечения (потенциальная потеря данных) - см. этот пост .

  • Преобразование обратно в JSON может показаться ненужным шагом, но -Compress стандартизирует форматирование вывода в одну строку без лишних пробелов, чтогарантирует, что случайные изменения в форматировании во вводе (если вы использовали входной текст JSON напрямую) игнорируются.


Если вы хотите знать, как два объекта, созданных в JSON, отличаются :

Примечание: полезно только в следующем сценарии limited - универсальный, надежныйРешение потребует гораздо больше усилий:

  • Входы имеют та же структура и различаются только именами / значениями свойств.

  • порядок (эквивалентных) свойств одинаков.

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 выполняется для обеспечения единообразного форматирования;в данном случае это печатный формат с ориентацией на строки, который позволяет сравнивать свойство за свойством.

  • Опять же, возможно, вам придется использовать -Depth, чтобы предотвратить усечение данных.

  • Для интерактивной проверки различий можно попробовать инструмент визуализации различий, например, встроенный в код Visual Studio, передав две строки JSON довольно-печатная форма через файлы в формате
    code --diff <file1> <file2>.


Что касается то, что вы пытались :

ConvertFrom-Json создает[pscustomobject] экземпляров, поэтому вы сравниваете два экземпляра этого типа:

  • Если вы используете -eq, проверяется равенство ссылок , потому что [pscustomobject] является ссылочным типом и не реализует пользовательское сравнение на равенство.

    • Следовательно, $po_ps_output -eq $po_python_output будет иметь значение $true, только если две переменные указывают на один и тот же объект в памяти - что явно не так, поэтому вы всегда получите $false.
  • Если вы используете Compare-Object, два экземпляра сравниваются по их значениям .ToString().

    • Начиная с PowerShell Core7.0.0-preview.4, к сожалению, вызов .ToString() для экземпляра [pscustomobject] приводит к пустой строке (''), что следует считать ошибкой - см. this GitHubПроблема .

    • Таким образом, Compare-Object $po_ps_output $po_python_output (бесполезно) считает два экземпляра равными и ничего не возвращает, так как равные объекты по умолчанию не выводятся (используйте-IncludeEqual, чтобы включить их).

...