我在power
shell 2.0中编写了一个脚本,目前无法升级到3.0或更高版本.在这个脚本中,我尝试使用此链接中的代码将一些数据序列化为
JSON(
PowerShell 2.0 ConvertFrom-Json and ConvertTo-Json implementation):
function ConvertTo-Json20([object] $item){ add-type -assembly system.web.extensions $ps_js=new-object system.web.script.serialization.javascriptSerializer return $ps_js.Serialize($item) }
我的问题是我以某种方式获得循环引用,我真的不知道为什么.我设置了一小段测试数据,结构在powershell中看起来像这样:
$testRoot = @{ "id" = "1" "children" = @( @{ "id" = "2" "children" = @( @{ "id" = "2"; }; @{ "id" = "3"; } ); }; @{ "id" = "4" "children" = @( @{ "id" = "5"; } ); } ) }
我知道它看起来很垃圾,但我只需要这种格式.
我需要序列化的结构有更多的层,所以更多的“孩子”,并有它变得奇怪的点.
当我尝试这个:
ConvertTo-Json20 $testRoot
一切正常.结构被解析如下:
{ "id":"1","children":[ { "id":"2","children":[ { "id":"2" },{ "id":"3" } ] },{ "id":"4","children":[ { "id":"5" } ] } ] }
但现在出现了问题.如上所述,结构有更多的层,所以我尝试这只是在数组中设置数据.
ConvertTo-Json20 @($testRoot)
但它不起作用我只是收到一条错误消息:
Exception in method "Serialize" with 1 argument(s): "While serializing an object of type "System.Management.Automation.PSParameterizedProperty" a circular reference was discovered." At C:\Users\a38732\Desktop\Temp.ps1:34 symbol:28 + return $ps_js.Serialize <<<< ($item) + CategoryInfo : NotSpecified: (:) [],MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException
(我翻译了德语的错误信息,所以在英文版本中可能会有一些不同的词……)
解决方法
一个问题是使用JavaScriptSerializer类本身.截至此日期为
documentation itself concedes it should not be used to serialize nor deserialize JSON.报价:
07001 should be used serialization and deserialization.
如果您能够使用像Json.NET这样的第三方库,这里有一个简单的函数,可以根据OP中的数据结构执行您所需的操作:
function ConvertTo-JsonNet { [CmdletBinding()] param( [Parameter(Mandatory)] $object,[Parameter(Mandatory)] [string]$jsonNetPath,[switch]$indent,[switch]$preserveReferencesHandling ) Add-Type -Path $jsonNetPath; $formatting = if ($indent.IsPresent) { [Newtonsoft.Json.Formatting]::Indented; } else { [Newtonsoft.Json.Formatting]::None; } $settings = New-Object Newtonsoft.Json.JsonSerializerSettings; if ($preserveReferencesHandling.IsPresent) { $settings.PreserveReferencesHandling = [Newtonsoft.Json.PreserveReferencesHandling]::Objects; } [Newtonsoft.Json.JsonConvert]::SerializeObject($object,$formatting,$settings); }
简单的用法,假设Newtonsoft.Json.dll与您的脚本位于同一目录中:
$dllPath = Join-Path $PSScriptRoot 'Newtonsoft.Json.dll'; ConvertTo-JsonNet @($testRoot) $dllPath;
输出:
[{"id":"1","children":[{"id":"2","children":[{"id":"2"},{"id":"3"}]},{"id":"4","children":[{"id":"5"}]}]}]
您可以从nuget package project site手动下载.dll.它具有.nupkg文件扩展名,但它是一个压缩存档,因此将扩展名重命名为.zip并进行设置.在lib子目录中,存在从2.0到4.5的.NET版本的.dll文件.