概要
NimのJSON処理をコツコツと
jsonモジュールのメソッドを一通り試します
以下メモ
JSONオブジェクトを構築
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* { "key1": "value1", "key2": 1 }
echo "# キーを指定して取得"
echo "key1=>" & $jsonObj["key1"]
echo "key2=>" & $jsonObj["key2"]
echo "# 型を指定して取得"
echo "key1=>" & jsonObj["key1"].getStr()
echo "key2=>" & $jsonObj["key2"].getInt()
echo "# 存在しないキーを指定"
#echo "keyx=>" & $jsonObj["keyx"]
echo "Error: unhandled exception: key not found: keyx [KeyError]"
echo "# デフォルト値を指定して取得(これもエラー)"
# echo "keyx=>" & $jsonObj["keyx"].getStr("")
echo "Error: unhandled exception: key not found: keyx [KeyError]"
(stdout)
# キーを指定して取得
key1=>"value1"
key2=>1
# 型を指定して取得
key1=>value1
key2=>1
# 存在しないキーを指定
Error: unhandled exception: key not found: keyx [KeyError]
# デフォルト値を指定して取得(これもエラー)
Error: unhandled exception: key not found: keyx [KeyError]
キーの存在チェック
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* { "key1": "value1", "key2": 1 }
echo "# キーの存在チェック"
echo "hasKey[key1]=>" & $jsonObj.hasKey("key1")
echo "hasKey[key3]=>" & $jsonObj.hasKey("key3")
echo "hasKey[key1]=>" & $jsonObj.contains("key1")
echo "hasKey[key3]=>" & $jsonObj.contains("key3")
(stdout)
# キーの存在チェック
hasKey[key1]=>true
hasKey[key3]=>false
hasKey[key1]=>true
hasKey[key3]=>false
JSONのPretty表示
import json
import os,strutils,tables
block:
let jsonObj = %* { "key1": "value1", "key2": 1 }
echo jsonObj.pretty()
(stdout)
{
"key1": "value1",
"key2": 1
}
JSONをファイルへ保存
import json
import os,strutils,tables
block:
let jsonObj = %* { "key1": "value1", "key2": 1 }
let f = open("sample.json", FileMode.fmWrite)
f.write(jsonObj.pretty())
f.close()
echo "file exists=>" & $"sample.json".existsFile
(stdout)
file exists=>true
JSONファイルの読み込み
import json
import os,strutils,tables
block:
let jsonObj1 = %* { "key1": "value1", "key2": 1 }
# さっき書き込んだファイルを読み込む
let jsonObj2 = parseFile("sample.json")
echo "compare json=>" , jsonObj1 == jsonObj2
echo jsonObj2.pretty
(stdout)
compare json=>true
{
"key1": "value1",
"key2": 1
}
JSON文字列からの構築
import json
import os,strutils,tables
block:
let jsonObj1 = %* { "key1": "value1", "key2": 1 }
# さっき書き込んだファイルを読み込む
let jsonStr = parseFile("sample.json").pretty
let jsonObj2 = parseJson(jsonStr)
echo "compare json=>" , jsonObj1 == jsonObj2
(stdout)
compare json=>true
JSONオブジェクトに属性を追加
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* { "key1": "value1", "key2": 1 }
# 文字列を追加
jsonObj["key3"] = newJString("value3")
echo "key3=>" & $jsonObj["key3"]
# %* で追加
jsonObj["key3"] = %* "value3"
echo "key3=>" & $jsonObj["key3"]
# 数値(int)を追加
jsonObj["key3"] = newJInt(999)
echo "key3=>" & $jsonObj["key3"]
# %* で追加
jsonObj["key3"] = %* 999
echo "key3=>" & $jsonObj["key3"]
# 配列を追加(newJArrayの引数は空なのでこれはできない))
# jsonObj["key3"] = newJArray([1,2,3,4])
# echo "key3=>" & $jsonObj["key3"]
# %* で追加
jsonObj["key3"] = %* [1,2,3,4]
echo "key3=>" & $jsonObj["key3"]
(stdout)
key3=>"value3"
key3=>"value3"
key3=>999
key3=>999
key3=>[1,2,3,4]
JSONのキー一覧を取得
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* { "key1": "value1", "key2": 1 }
let fields: OrderedTable[string,JsonNode] = jsonObj.getFields()
var keys: seq[string] = @[]
for key in fields.keys:
keys.add key
echo "keys=>" & keys
(stdout)
@["keys=>", "key1", "key2"]
属性の型を確認する
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* {
"key1": "value1",
"key2": 1,
"key3": true,
"key4": 3.141592,
"key5": nil,
"key6": [11,2,3],
"key7": {"name": "object"}
}
# JsonNodeKindは省略可能
echo jsonObj["key1"].kind == JsonNodeKind.JString
echo jsonObj["key2"].kind == JsonNodeKind.JInt
echo jsonObj["key3"].kind == JsonNodeKind.JBool
echo jsonObj["key4"].kind == JsonNodeKind.JFloat
echo jsonObj["key5"].kind == JsonNodeKind.JNull
echo jsonObj["key6"].kind == JsonNodeKind.JArray
echo jsonObj["key7"].kind == JsonNodeKind.JObject
(stdout)
true
true
true
true
true
true
true
JSONのオブジェクト階層を探索しながら値を取得
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* {
"parent": {
"child1": "value1",
"child2": {
"child3": [1,2,3]
}
}
}
# {}演算子を使って、親・子のキーを並べて指定する
echo "parent.child1=>" & $jsonObj{"parent","child1"}
echo "parent.child2.child3=>" & $jsonObj{"parent","child2","child3"}
(stdout)
parent.child1=>"value1"
parent.child2.child3=>[1,2,3]
属性の削除
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* { "key1": "value1", "key2": 1 }
# deleteで削除
jsonObj.delete("key1")
echo jsonObj.pretty
echo "# もう一度deleteで削除->キーが無いのでエラー"
echo """jsonObj.delete("key1")"""
echo "Error: unhandled exception: key not in object [IndexError]"
(stdout)
{
"key2": 1
}
# もう一度deleteで削除->キーが無いのでエラー
jsonObj.delete("key1")
Error: unhandled exception: key not in object [IndexError]
JSONエスケープ処理
import json
import os,strutils,tables
block:
echo "escapeJson=>" & escapeJson("test1\ntest2\n")
(stdout)
escapeJson=>"test1\ntest2\n"
整形しないでJson文字列を作成(toUgly)
import json
import os,strutils,tables
block:
let jsonObj = %* {
"parent": {
"child1": "value1",
"child2": {
"child3": [1,2,3]
}
}
}
var result = ""
toUgly(result,jsonObj)
echo "toUgly=>" & result
(stdout)
toUgly=>{"parent":{"child1":"value1","child2":{"child3":[1,2,3]}}}
イテレータ(items) 対象は配列オブジェクトのみ
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* [
{"key1": "value1"},
{"key2": 1},
{"key3": true},
{"key4": 3.141592},
{"key5": nil},
{"key6": [1,2,3]},
{"key7": {"name": "object"}}
]
for item in jsonObj.items:
echo "==================="
echo $item
(stdout)
===================
{"key1":"value1"}
===================
{"key2":1}
===================
{"key3":true}
===================
{"key4":3.141592}
===================
{"key5":null}
===================
{"key6":[1,2,3]}
===================
{"key7":{"name":"object"}}
イテレータ(mitems) 対象はミュータブルなJson配列オブジェクトのみ。
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
var jsonObj = %* [
{"key1": "value1"},
{"key2": 1},
{"key3": true},
{"key4": 3.141592},
{"key5": nil},
{"key6": [1,2,3]},
{"key7": {"name": "object"}}
]
for item in jsonObj.mitems:
# 中身を変更できる
item["message"] = %* "hello"
echo "==================="
echo $item
(stdout)
===================
{"key1":"value1","message":"hello"}
===================
{"key2":1,"message":"hello"}
===================
{"key3":true,"message":"hello"}
===================
{"key4":3.141592,"message":"hello"}
===================
{"key5":null,"message":"hello"}
===================
{"key6":[1,2,3],"message":"hello"}
===================
{"key7":{"name":"object"},"message":"hello"}
イテレータ(pairs) 対象はオブジェクトのみ。
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
let jsonObj = %* {
"key1": "value1",
"key2": 1,
"key3": true,
"key4": 3.141592,
"key5": nil,
"key6": [1,2,3],
"key7": {"name": "object"}
}
for item in jsonObj.pairs:
echo "==================="
echo "key=>" & $item.key
echo "val=>" & $item.val
(stdout)
===================
key=>key1
val=>"value1"
===================
key=>key2
val=>1
===================
key=>key3
val=>true
===================
key=>key4
val=>3.141592
===================
key=>key5
val=>null
===================
key=>key6
val=>[1,2,3]
===================
key=>key7
val=>{"name":"object"}
イテレータ(mpairs) 対象はミュータブルなJsonオブジェクト
import json
import os,strutils,tables
block:
# %* をつけてJsonオブジェクトを構築
var jsonObj = %* {
"key1": "value1",
"key2": 1,
"key3": true,
"key4": 3.141592,
"key5": nil,
"key6": [1,2,3],
"key7": {"name": "object"}
}
# mpairsで列挙
for item in jsonObj.mpairs:
echo "==================="
echo "key=>" & $item.key
echo "val=>" & $item.val
jsonObj[item.key] = %* "message"
echo "書き換え結果=>" & jsonObj.pretty
(stdout)
===================
key=>key1
val=>"value1"
===================
key=>key2
val=>1
===================
key=>key3
val=>true
===================
key=>key4
val=>3.141592
===================
key=>key5
val=>null
===================
key=>key6
val=>[1,2,3]
===================
key=>key7
val=>{"name":"object"}
書き換え結果=>{
"key1": "message",
"key2": "message",
"key3": "message",
"key4": "message",
"key5": "message",
"key6": "message",
"key7": "message"
}
JSONオブジェクトからオブジェクトに変換
import json
import os,strutils,tables
block:
let jsonNode = parseJson("""
{
"person": {
"name": "Nimmer",
"age": 21
},
"list": [1, 2, 3, 4]
}
""")
type
Person = object
name: string
age: int
Data = object
person: Person
list: seq[int]
var data = to(jsonNode, Data)
echo "data.person.name=>" & data.person.name
echo "data.person.age=>" & $data.person.age
echo "data.list=>" & $data.list
(stdout)
data.person.name=>Nimmer
data.person.age=>21
data.list=>@[1, 2, 3, 4]
JSON配列内の要素を配列オブジェクトに変換
import json
import os,strutils,tables
block:
let jsonNode = parseJson("""[
{
"person": {
"name": "Nimmer",
"age": 21
},
"list": [1, 2, 3, 4]
}]
""")
type
Person = object
name: string
age: int
Data = object
person: Person
list: seq[int]
var data = to(jsonNode, seq[Data])
echo "data[0].person.name=>" & data[0].person.name
echo "data[0].person.age=>" & $data[0].person.age
echo "data[0].list=>" & $data[0].list
(stdout)
data[0].person.name=>Nimmer
data[0].person.age=>21
data[0].list=>@[1, 2, 3, 4]