我想得到一个Hashtable的JSON表示,如下所示:
@{Path="C:\temp"; Filter="*.js"}
Run Code Online (Sandbox Code Playgroud)
ConvertTo-Json
结果是:
{
"Path": "C:\\temp",
"Filter": "*.js"
}
Run Code Online (Sandbox Code Playgroud)
但是,如果您将JSON字符串转换回来,ConvertFrom-Json
则不会获得HashTable,而是获得PSCustomObject.
那么如何才能可靠地序列化上面的Hashmap呢?
sod*_*low 33
$json = @{Path="C:\temp"; Filter="*.js"} | ConvertTo-Json
$hashtable = @{}
(ConvertFrom-Json $json).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value }
Run Code Online (Sandbox Code Playgroud)
JavaScriptSerializer从.NET3.5开始可用(可以安装在XP上,包含在Win7和更新版本中),它比Convert-FromJSON快几倍,它可以正确解析嵌套对象,数组等.
function Parse-JsonFile([string]$file) {
$text = [IO.File]::ReadAllText($file)
$parser = New-Object Web.Script.Serialization.JavaScriptSerializer
$parser.MaxJsonLength = $text.length
Write-Output -NoEnumerate $parser.DeserializeObject($text)
}
Run Code Online (Sandbox Code Playgroud)
小智 6
这篇文章的答案是一个很好的开始,但是当您开始获得更复杂的 json 表示形式时就有点天真了。
下面的代码将解析嵌套的 json 数组和 json 对象。
[CmdletBinding]
function Get-FromJson
{
param(
[Parameter(Mandatory=$true, Position=1)]
[string]$Path
)
function Get-Value {
param( $value )
$result = $null
if ( $value -is [System.Management.Automation.PSCustomObject] )
{
Write-Verbose "Get-Value: value is PSCustomObject"
$result = @{}
$value.psobject.properties | ForEach-Object {
$result[$_.Name] = Get-Value -value $_.Value
}
}
elseif ($value -is [System.Object[]])
{
$list = New-Object System.Collections.ArrayList
Write-Verbose "Get-Value: value is Array"
$value | ForEach-Object {
$list.Add((Get-Value -value $_)) | Out-Null
}
$result = $list
}
else
{
Write-Verbose "Get-Value: value is type: $($value.GetType())"
$result = $value
}
return $result
}
if (Test-Path $Path)
{
$json = Get-Content $Path -Raw
}
else
{
$json = '{}'
}
$hashtable = Get-Value -value (ConvertFrom-Json $json)
return $hashtable
}
Run Code Online (Sandbox Code Playgroud)