在PowerShell中如何将哈希表转换为JSON字符串?

5
我正在尝试将一个哈希表转换为JSON对象,以便在PowerShell 2.0的Web服务中使用。
$testhash = @{
    Name = 'John Doe'
    Age = 10
    Amount = 10.1
    MixedItems = (1,2,3,"a")
    NestedHash = @{
        nestedkey = "nextedvalue"
    }
}

function toJson($obj){

    $ms = New-Object IO.MemoryStream
    $type = $obj.getType()
    [Type[]]$types = ($obj | select -expand PsTypeNames |  Select -unique) + [type]'System.Management.Automation.PSObject'
    $js = New-Object System.Runtime.Serialization.Json.DataContractJsonSerializer $type, $types, ([int]::MaxValue), $false, $null, $false
    $js.writeObject($ms, $obj) | out-null
    $utf8.GetString( $ms.ToArray(), 0, $ms.Length )
    $ms.Dispose() | out-null
}

toJson $testhash
'[{"Key":"Name","Value":"John Doe"},{"Key":"Age","Value":10},{"Key":"Amount","Value":10.1},{"Key":"NestedHash","Value":[{"__type":"KeyValuePairOfanyTypeanyType:#System.Collections.Generic","key":"nestedkey","value":"nextedvalue"}]},{"Key":"MixedItems","Value":[1,2,3,"a"]}]'

我正在使用DataContractJsonSerializer构造函数,以一种应该可以抑制类型信息的方式,但显然没有成功。我也被它提取键值对的方式所吸引,但我不希望它这样做。我做错了什么?

3个回答

16

2
我希望我能使用PowerShell v3 =) - reconbot
这个_shell_非常强大 :) - S Raghav

3

我根据这里的脚本进行了修改,如下所示:

$testhash = @{
    Name = 'John Doe'
    Age = 10
    Amount = 10.1
    MixedItems = (1,2,3,"a")
    NestedHash = @{
        nestedkey = "nextedvalue"
    }
}

function Read-Stream {
PARAM(
   [Parameter(Position=0,ValueFromPipeline=$true)]$Stream
)
process {
   $bytes = $Stream.ToArray()
   [System.Text.Encoding]::UTF8.GetString($bytes,0,$bytes.Length)
}}

function New-Json {
[CmdletBinding()]
param([Parameter(ValueFromPipeline=$true)][HashTable]$InputObject) 
begin { 
   $ser = @{}
   $jsona = @()
}
process {
   $jsoni = 
   foreach($input in $InputObject.GetEnumerator() | Where { $_.Value } ) {
      if($input.Value -is [Hashtable]) {
         '"'+$input.Key+'": ' + (New-JSon $input.Value)
      } else {
         $type = $input.Value.GetType()
         if(!$Ser.ContainsKey($Type)) {
            $Ser.($Type) = New-Object System.Runtime.Serialization.Json.DataContractJsonSerializer $type
         }
         $stream = New-Object System.IO.MemoryStream
         $Ser.($Type).WriteObject( $stream, $Input.Value )
         '"'+$input.Key+'": ' + (Read-Stream $stream)
      }
   }

   $jsona += "{`n" +($jsoni -join ",`n")+ "`n}"
}
end { 
   if($jsona.Count -gt 1) {
      "[$($jsona -join ",`n")]" 
   } else {
      $jsona
   }
}}

$testHash | New-Json

这似乎是序列化函数应该自己完成的事情,不是吗?无论如何 - 这几乎完美地工作 - 在两个嵌套哈希的级别上失败。 - reconbot
@wizard - 我认为它应该是用于简单的哈希表。你可以四处看看,已经有像我链接的脚本一样执行JSON解析的脚本了。 - manojlds
我最终使用了http://poshcode.org/2930,它有一些问题,但足够好用 - 总有一天powershell 3.0会发布,我会回顾这些浪费的时间并感到不满。 - reconbot

0
一个漂亮干净的一行代码。
ConvertTo-Json ([System.Management.Automatio.PSObject] $testhash)

欢迎来到 [so]!通常情况下,如果答案包括代码意图的解释以及为什么这样做可以解决问题而不会引入其他问题,那么它们会更有帮助。 - lucascaro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接