20

サイズが 2 MB を超える JSON 文字列を変換するときに、PowerShell v3 を使用すると問題が発生します。PowerShell で使用される JSON シリアライザーの既定の制限は 2MB に設定されており、これがエラーを説明しています。

ただし、より小さなセットで ConvertFrom-Json を使用してオブジェクトを逆シリアル化すると (内部コレクションがより小さく、より大きくなるさまざまなデータ オブジェクトを取得しましたが、それらは同じオブジェクトです)、簡単にアクセスできるすべてのプロパティを備えた非常に優れたオブジェクトが返されます。

シリアライザーの制限を克服するために、データを手動で逆シリアル化しようとしました。

$jsser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$jsser.MaxJsonLength = $jsser.MaxJsonLength * 10
$jsser.RecursionLimit = 99    

$outObject = $jsser.DeserializeObject($json)

内部コレクションが逆シリアル化されていないようで、プロパティを実行しようとすると、空の結果が返されます。

私の質問:

  1. 仮定はConvertFrom-Json、いくつかの追加の魔法を行うか、シリアル化の前に何らかの方法でオブジェクトのテンプレートを作成します。それを複製する方法はありますか?

  2. 私が得るオブジェクトは常にPSCustomObjectです。セットアップしたいオブジェクトを取得した場合、ConvertFrom-JsonそれをJsonSerializerのオブジェクトタイプとして使用する方法はありますか?

4

4 に答える 4

6

Invoke-RestMethod結果に大きなJSONコレクションを使用すると、同じ問題が発生しました。最終的に、PowerShell および Json.NET を使用した JSON の解析のメソッドを適応させて、JSON コレクションを PowerShell オブジェクトに変換しました。

# .NET JSON Serializer 
$global:javaScriptSerializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
$global:javaScriptSerializer.MaxJsonLength = [System.Int32]::MaxValue
$global:javaScriptSerializer.RecursionLimit = 99

# Functions necessary to parse JSON output from .NET serializer to PowerShell Objects
function ParseItem($jsonItem) {
        if($jsonItem.PSObject.TypeNames -match "Array") {
                return ParseJsonArray($jsonItem)
        }
        elseif($jsonItem.PSObject.TypeNames -match "Dictionary") {
                return ParseJsonObject([HashTable]$jsonItem)
        }
        else {
                return $jsonItem
        }
}

function ParseJsonObject($jsonObj) {
        $result = New-Object -TypeName PSCustomObject
        foreach ($key in $jsonObj.Keys) {
                $item = $jsonObj[$key]
                if ($item) {
                        $parsedItem = ParseItem $item
                } else {
                        $parsedItem = $null
                }
                $result | Add-Member -MemberType NoteProperty -Name $key -Value $parsedItem
        }
        return $result
}

function ParseJsonArray($jsonArray) {
        $result = @()
        $jsonArray | ForEach-Object {
                $result += , (ParseItem $_)
        }
        return $result
}

function ParseJsonString($json) {
        $config = $javaScriptSerializer.DeserializeObject($json)
        return ParseJsonObject($config)
}
于 2015-02-19T08:39:35.330 に答える