从JSON创建Hashtable

ehxuflar  于 2023-04-13  发布在  其他
关注(0)|答案(7)|浏览(345)

我想得到一个像这样的Hashtable的JSON表示:

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

ConvertTo-Json导致:

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

但是,如果您使用ConvertFrom-Json将该JSON字符串转换回来,则不会得到HashTable,而是得到PSCustomObject。
那么,如何可靠地序列化上面的Hashmap呢?

nxowjjhe

nxowjjhe1#

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

$hashtable = @{}

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

改编自PSCustomObject to Hashtable

mbzjlibv

mbzjlibv2#

这里的讨论有点晚,但在PowerShell 6(核心)中,ConvertFrom-Json中有一个-AsHashtable参数。

mkh04yzy

mkh04yzy3#

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)
}
klr1opcd

klr1opcd4#

这篇文章的答案是一个很好的开始,但是当你开始使用更复杂的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
}
l3zydbqr

l3zydbqr5#

我相信Converting JSON to a hashtable中提供的解决方案更接近于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
ffx8fchx

ffx8fchx6#

从这里的链接导入代码https://4sysops.com/archives/convert-json-to-a-powershell-hash-table/

function ConvertTo-Hashtable {
[CmdletBinding()]
[OutputType('hashtable')]
param (
    [Parameter(ValueFromPipeline)]
    $InputObject
)

process {
    ## Return null if the input is null. This can happen when calling the function
    ## recursively and a property is null
    if ($null -eq $InputObject) {
        return $null
    }

    ## Check if the input is an array or collection. If so, we also need to convert
    ## those types into hash tables as well. This function will convert all child
    ## objects into hash tables (if applicable)
    if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) {
        $collection = @(
            foreach ($object in $InputObject) {
                ConvertTo-Hashtable -InputObject $object
            }
        )

        ## Return the array but don't enumerate it because the object may be pretty complex
        Write-Output -NoEnumerate $collection
    } elseif ($InputObject -is [psobject]) { ## If the object has properties that need enumeration
        ## Convert it to its own hash table and return it
        $hash = @{}
        foreach ($property in $InputObject.PSObject.Properties) {
            $hash[$property.Name] = ConvertTo-Hashtable -InputObject $property.Value
        }
        $hash
    } else {
        ## If the object isn't an array, collection, or other object, it's already a hash table
        ## So just return it.
        $InputObject
    }
}

}然后我们可以通过管道调用这个函数:$json|ConvertFrom-Json|ConvertTo-HashTable

ih99xse1

ih99xse17#

你可以写一个函数把psobject转换成hashtable。
我在这里写了一个答案:enter link description here

相关问题