2011-12-07 18 views
5

मैं पावरहेल 2.0 के साथ एक वेब सेवा में उपयोग के लिए एक हैशटेबल को एक जेसन ऑब्जेक्ट में बदलने की कोशिश कर रहा हूं।मैं शक्तियों में एक json स्ट्रिंग में एक hastable कैसे परिवर्तित कर सकते हैं?

$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 उपयोग कर रहा हूँ, लेकिन यह स्पष्ट रूप से नहीं। मैं इसके द्वारा निकालने वाली कुंजी और मूल्य जोड़ों से भी खुश हूं लेकिन मैं इसे ऐसा नहीं करना चाहता हूं। मैं क्या गलत कर रहा हूं?

उत्तर

3

मैं 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 
+0

यह कुछ serialize समारोह अपने आप पर क्या करना चाहिए की तरह लगता है, नहीं? किसी भी तरह से - यह लगभग पूरी तरह से काम करता है - नेस्टेड हैश के दो स्तरों पर विफल रहता है। – reconbot

+0

@ जादूगर - मुझे लगता है कि यह सरल हैशटेबल्स के लिए होना चाहिए। आप देख सकते हैं, पहले से ही स्क्रिप्ट्स हैं जैसे मैंने JSON पार्सिंग करने के लिए लिंक किया है। – manojlds

+0

मैंने http://poshcode.org/2930 का उपयोग करके समाप्त किया जिसमें मुद्दों के साथ पर्याप्त काम करता है - एक दिन पावरहेल 3.0 उपलब्ध होगा और मैं इन बर्बाद घंटों पर वापस देखूंगा और परेशान रहूंगा – reconbot

16

ठीक है, तो 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

+2

मेरी इच्छा है कि मैं powerhell v3 =) – reconbot

+0

तो साफ और सरल !!! – lantrix

+0

इस _shell_ में बहुत सारे _power_ हैं :) – raghav710

संबंधित मुद्दे