Help us understand the problem. What is going on with this article?

nimのJSON操作

More than 1 year has passed since last update.

概要

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]
6in
窓際エンジニアです
future
ITを武器とした課題解決型のコンサルティングサービスを提供します
http://future-architect.github.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away