タイトル通り。
ハッシュテーブルだと思い込んでちょっと悩んだ。
JSONから変換したオブジェクトにAddできない?
JSONに要素を追加する際、文字列を直接切り張りしていたらキリストがお嘆きになろうから、オブジェクトに変換して操作しようと思った。
が、エラーになる。
$JSON = @'
{
"alpha": "One",
"beta" : "Two",
"gamma": "Three",
"delta": [ "Four", "Five" ]
}
'@
$Object = $JSON | ConvertFrom-Json
$Object.Add("nu","Six") #エラーになる
[System.Management.Automation.PSCustomObject] に 'Add' という
名前のメソッドが含まれないため、メソッドの呼び出しに失敗しました。
おや?エラーを見るとPSCustomObjectとある。
あれ?Hashtableじゃない…。
ConvertFrom-JsonはPSCustomObjectを出力する
何だこれと調べたところ、公式ドキュメントにしっかり書いてあった。
ConvertFrom-Json(公式ドキュメント)
ConvertFrom-Jsonコマンドレットは、JavaScript Object Notation(JSON)形式の文字列を、JSON文字列の各フィールドのプロパティを持つカスタムPSCustomObjectオブジェクトに変換します
$Array = @{
alpha = "One"
beta = "Two"
gamma = "Three"
delta = @("Four","Five")
}
$Array.GetType()
# JSONにConvertして戻すとPSCustomObjectで出てくる
$Array_AfterConvert = $Array | ConvertTo-Json | ConvertFrom-Json
$Array_AfterConvert.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Hashtable System.Object
True False PSCustomObject System.Object
仕様です。
思い込んでないで疑え、迷うより公式読めって話ですね。
これで終わりだと寂しいので当初の目的である要素追加や型変換などのことを以下に。
PSCustomObjectに要素を追加する
Add-Member
を使う。
Add-Member(公式ドキュメント)
$JSON =@'
{
"alpha": "One",
"beta" : "Two",
"gamma": "Three",
"delta": ["Four","Five"]
}
'@
$Object = $JSON | ConvertFrom-Json
Write-Host "Add前"
$Object | Format-List
$Object | Add-Member -NotePropertyName "nu" -NotePropertyValue "Six"
Write-Host "Add後"
$Object | Format-List
Write-Host "Get-Member"
$Object | Get-Member
Add前
alpha : One
beta : Two
gamma : Three
delta : {Four, Five}
Add後
alpha : One
beta : Two
gamma : Three
delta : {Four, Five}
nu : Six
Get-Member
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
alpha NoteProperty string alpha=One
beta NoteProperty string beta=Two
delta NoteProperty Object[] delta=System.Object[]
gamma NoteProperty string gamma=Three
nu NoteProperty string nu=Six
PSCustomObjectからHashtableに変換したい
コマンドレット一発変換とはいかない。
先にハッシュテーブルを作っておいて、PSCustomObjectから読み込んで代入するといいようだ。ジャグ配列の時は注意な!な話もあってまだ使ってない。
PSCustomObject について知りたかったことのすべて(MSのドキュメント)
stackoverflow:Create Hashtable from JSON
AsHashtableパラメータ指定して変換(PowerShell 7)
PowerShell 7 では、ConvertFrom-Json -AsHashtable
とパラメータ指定するとハッシュテーブルに変換してくれる。7を使える環境なら悩まなくていい。
ConvertFrom-Json(公式ドキュメント)
[PowerShell 7] ConvertFrom-Json を使用して JSON データを読み込む
追記:JavaScriptSerializer.Deserializeメソッドで変換
JavaScriptSerializer.Deserialize
メソッドでJSONをハッシュテーブルに変換できる。PowerShell 7でなくても使える。(ver5で確認)
PowerShell で JSON 変換をするときに発生するアレコレ
JavaScriptSerializer クラス
JavaScriptSerializer.Deserializeメソッド