我正在用 powershell 2.0 编写脚本,现在无法升级到 3.0 或更高版本。在此脚本中,我尝试使用此链接 ( PowerShell 2.0 ConvertFrom-Json and ConvertTo-Json implementation ) 中的代码将一些数据序列化为 JSON:

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"; 
                } 
            ); 
        } 
    ) 
} 

我知道它看起来很垃圾,但我只需要这种格式。

我需要序列化的结构有更多的层,所以更多的“ child ”并且有一点变得奇怪。

当我尝试这个时:
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 .报价:

Json.NET 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子目录中有 .dll 文件,适用于 2.0 到 4.5 的 .NET 版本。


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!