web-dev-qa-db-ja.com

JSONからハッシュテーブルを作成する

このようなハッシュテーブルのJSON表現を取得したい:

@{Path="C:\temp"; Filter="*.js"}

ConvertTo-Json結果:

{
    "Path":  "C:\\temp",
    "Filter":  "*.js"
}

ただし、そのJSON文字列をConvertFrom-Json HashTableではなく、PSCustomObjectを取得します。

では、どうすれば上記のハッシュマップを確実にシリアル化できますか?

17
Marc
$json = @{Path="C:\temp"; Filter="*.js"} | ConvertTo-Json

$hashtable = @{}

(ConvertFrom-Json $json).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value }

PSCustomObjectからHashtableへの適応

30
sodawillow

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)
}
8
wOxxOm

この投稿に対する答えは素晴らしい出発点ですが、より複雑な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
}
3
Esten Rye

ここでの議論に少し遅れましたが、PowerShell 6(コア)では ConvertFrom-Json-AsHashtableパラメーターがあります。

3
ThePoShWolf

JSONからハッシュテーブルへの変換 で提示されたソリューションは、 ConvertFrom-Json のPowerShell 6.0実装に近いと思います

いくつかの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
3