【问题标题】:How can I convert a hastable to a json string in powershell?如何在powershell中将hastable转换为json字符串?
【发布时间】:2012-01-15 05:13:34
【问题描述】:

我正在尝试将哈希表转换为 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 constructor 的方式应该抑制类型信息,但显然不是。我也对它提取键和值对感到好笑,但我也不希望它这样做。我做错了什么?

【问题讨论】:

    标签: .net json powershell powershell-2.0


    【解决方案1】:

    好的,所以 manojlds 回答了 v2,所以我将在这里抛出 v3 等效项:

    PS> @{name="oisin"; age=37} | convertto-json
    {
        "age":  37,
        "name":  "oisin"
    }
    

    相当干净,对吧?

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

    【讨论】:

    • 我希望我可以使用 powershell v3 =)
    • 在这个 shell 中有相当多的 power :)
    【解决方案2】:

    我改编了here的脚本如下:

    $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
    

    【讨论】:

    • 这似乎是序列化函数应该自己做的事情,不是吗?无论哪种方式 - 这几乎可以完美地工作 - 在两个嵌套哈希级别上都失败了。
    • @wizard - 我认为它应该用于简单的哈希表。你可以看看,已经有像我这样链接到做 JSON 解析的脚本了。
    • 我最终使用了 poshcode.org/2930,它有问题但运行良好 - 有一天 powershell 3.0 将可用,我会回顾这些浪费的时间并感到沮丧
    【解决方案3】:

    一个漂亮干净的单线。

    ConvertTo-Json ([System.Management.Automatio.PSObject] $testhash)
    

    【讨论】:

    • 欢迎来到Stack Overflow!一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决了问题,那么答案会更有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多