Ответ 1
$json = @{Path="C:\temp"; Filter="*.js"} | ConvertTo-Json
$hashtable = @{}
(ConvertFrom-Json $json).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value }
Адаптировано из PSCustomObject для Hashtable
Я хочу получить JSON-представление Hashtable, например:
@{Path="C:\temp"; Filter="*.js"}
ConvertTo-Json
приводит к:
{
"Path": "C:\\temp",
"Filter": "*.js"
}
Однако, если вы конвертируете эту строку JSON с помощью ConvertFrom-Json
, вы не получите HashTable, а PSCustomObject.
Итак, как можно надежно сериализовать вышеупомянутый Hashmap?
$json = @{Path="C:\temp"; Filter="*.js"} | ConvertTo-Json
$hashtable = @{}
(ConvertFrom-Json $json).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value }
Адаптировано из PSCustomObject для Hashtable
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)
}
Ответ на этот пост - отличное начало, но немного наивно, когда вы начинаете получать более сложные 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
}
Я верю, что решение, представленное в Преобразование JSON в хэш-таблицу ближе к реализации PowerShell 6.0 ConvertFrom-Json
Я попробовал несколько источников JSON, и у меня всегда была правильная хеш-таблица.
$mappings = @{
Letters = (
"A",
"B")
Numbers = (
"1",
"2",
"3")
Yes = 1
False = "0"
}
# TO JSON
$jsonMappings = $mappings | ConvertTo-JSON
$jsonMappings
# Back to hashtable
# In PowerShell 6.0 would be:
# | ConvertFrom-Json -AsHashtable
$jsonMappings | ConvertFrom-Json -As hashtable
Немного поздно для обсуждения здесь, но в PowerShell 6 (Core) в ConvertFrom-Json есть параметр -AsHashtable
.
Вы можете написать функцию, конвертирующую psobject в hashtable.
Я написал ответ здесь: введите описание ссылки здесь