如何在PowerShell 5.1中将JSON字符串转换为指定格式的Hashtable
问题:PowerShell 5.1中JSON转Hashtable格式不符的调整方法
问题背景
在PowerShell 5.1版本中将JSON字符串转换为指定格式的Hashtable时,使用现有ConvertTo-Hashtable函数得到的输出格式不符合预期,需要调整以达到目标格式。
我的代码
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示例
$json = '[ { "type": "IP", "Fields": [ { "Column": "FileHash", "Id": "Address" } ] } ]'
当前代码输出格式
Name Value ---- ----- Fields {System.Collections.Hashtable} type IP
期望输出格式
Key : type Value : IP Name : type Key : Fields Value : {FileHash} Name : Fields
解决方案
原函数本身已经正确将JSON转换为Hashtable对象,问题出在PowerShell默认的表格显示格式和你的期望不符。以下两种方法可以实现目标输出:
方法1:修改函数直接输出自定义格式
如果希望转换后直接得到目标格式的输出,可以修改函数,将Hashtable的键值对转为自定义结构输出:
function ConvertTo-CustomHashtableView { [CmdletBinding()] param ( [Parameter(ValueFromPipeline)] $InputObject ) process { if ($null -eq $InputObject) { return $null } # 处理数组/集合类型 if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) { foreach ($object in $InputObject) { ConvertTo-CustomHashtableView -InputObject $object } } # 处理PS对象,转为自定义格式输出 elseif ($InputObject -is [psobject]) { $hash = @{} foreach ($property in $InputObject.PSObject.Properties) { $hash[$property.Name] = ConvertTo-CustomHashtableView -InputObject $property.Value } # 遍历Hashtable生成目标格式 foreach ($key in $hash.Keys) { # 处理Fields字段的Value显示,提取Column值 $displayValue = if ($hash[$key] -is [array] -and $hash[$key][0].Column) { "{$($hash[$key][0].Column)}" } else { $hash[$key] } # 输出自定义键值对格式 [PSCustomObject]@{ Key = $key Value = $displayValue Name = $key } # 添加空行分隔 "" } } # 基础类型直接返回 else { $InputObject } } }
使用方式:
$json | ConvertFrom-Json | ConvertTo-CustomHashtableView
方法2:保留原Hashtable结构,仅调整输出格式
如果需要保留Hashtable的原始结构,只是在输出时展示为目标格式,可以在转换完成后手动遍历输出:
# 先用原函数完成JSON到Hashtable的转换 $result = $json | ConvertFrom-Json | ConvertTo-Hashtable # 遍历结果生成目标格式输出 foreach ($key in $result[0].Keys) { # 处理Fields字段的Value显示 $value = if ($key -eq 'Fields') { "{$($result[0][$key][0].Column)}" } else { $result[0][$key] } # 输出指定格式的内容 " Key : $key" " Value : $value" " Name : $key`n`n" }
内容的提问来源于stack exchange,提问作者dev333
相关产品推荐
相关产品推荐

