如何在PowerShell中将hastable转换为json字符串?

rec*_*bot 5 .net powershell json powershell-2.0

我正在尝试将哈希表转换为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"]}]'
Run Code Online (Sandbox Code Playgroud)

我正在以一种应该抑制类型信息的方式使用DataContractJsonSerializer构造函数,但显然不是.我也很高兴它提取键和值对,但我想让它不这样做.我究竟做错了什么?

x0n*_*x0n 16

好的,所以manojlds回答了v2,所以我只是在这里抛出v3等价物:

PS> @{name="oisin"; age=37} | convertto-json
{
    "age":  37,
    "name":  "oisin"
}
Run Code Online (Sandbox Code Playgroud)

相当干净吧?

PowerShell 3.0 CTP2:http://www.microsoft.com/download/en/details.aspx?id = 27548

  • 我希望我可以使用powershell v3 =) (2认同)

man*_*lds 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
Run Code Online (Sandbox Code Playgroud)