2011-12-07 42 views
5

Tôi đang cố gắng chuyển đổi một hashtable thành một đối tượng json để sử dụng trong một dịch vụ web với PowerShell 2.0.Làm thế nào tôi có thể chuyển đổi một hastable thành một chuỗi json trong PowerShell?

$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"]}]' 

Tôi đang sử dụng DataContractJsonSerializer constructor theo cách nên chặn thông tin loại nhưng rõ ràng là không. Tôi cũng thích thú vì nó trích xuất các cặp khóa và giá trị nhưng tôi cũng muốn nó không làm điều đó. Tôi đang làm gì sai?

Trả lời

3

tôi chuyển thể kịch bản từ here như sau:

$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 
+0

Điều này có vẻ giống như chức năng tuần tự hóa nên tự thực hiện, phải không? Dù bằng cách nào - điều này hoạt động gần như hoàn hảo - không thành công trên hai cấp độ băm lồng nhau. – reconbot

+0

@wizard - Đó là nghĩa vụ phải được cho hashtables đơn giản tôi nghĩ. Bạn có thể xem xét aroudn, đã có các kịch bản như tôi đã liên kết để thực hiện phân tích cú pháp JSON. – manojlds

+0

Tôi đã kết thúc bằng cách sử dụng http://poshcode.org/2930 trong đó có vấn đề nhưng hoạt động tốt đủ - một ngày powershell 3.0 sẽ có sẵn và tôi sẽ nhìn lại những giờ lãng phí và bị khó chịu – reconbot

16

Ok, vậy manojlds trả lời cho v2 vì vậy tôi sẽ chỉ ném lên v3 tương đương ở đây:

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

Khá một chút bụi , đúng?

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

+2

Tôi muốn tôi có thể sử dụng powershell v3 =) – reconbot

+0

Vì vậy, sạch sẽ và đơn giản !!! – lantrix

+0

Có khá nhiều _power_ trong _shell_ này :) – raghav710

Các vấn đề liên quan