JSONに関する世界観です。
JavaScriptやPythonなどと親和性の高いデータ記述フォーマット。Ajaxなどで使われたりするほか、MongoDBなどのNoSQLデータベースでも使われる。
以下は具体例。
{
"Japan": [ "yen", 50 ],
"EU": {
"Germany": [ "euro", 100 ],
"UK": ["pound", 200 ]
}
}
詳しくは以下が参考になる。
jqコマンドは、JSONを操作するための便利なコマンド。curlなどとともに使用する。
curlも参照のこと。
2025.04.24
PythonからJSON形式のデータを扱うには、jsonというAPIを使う。
PythonオブジェクトをJSONデータにエンコーディングするにはjson.dumps()を使う(直列化)。
JSONデータをPythonオブジェクトにデコーディングするにはjson.loads()を使う(脱直列化)。
シリアライズも参照のこと。
Ruby on RailsのようなWebフレームワークでは、人間が読むHTMLを出力する代わりに、機械が読むためのJSONデータを吐き出すことができる。
こうした単純なWeb上のJSONデータ以外にも、Web APIであるSOAPやRESTを使うことで、Web上のさまざまなデータをネットワーク経由で取得し、操作し、処理することができる。特に、RESTではJSON形式が一般的に利用されている(一応XMLにも対応している)。
JSONは以前XMLが使われていていたAjaxの「インタラクティブWebアプリ」でも、XMLの代わりとなるシンプルなデータ記述フォーマットとなっている。
また、ドキュメント指向データベースのMongoDBではJSONライクなデータ構造が格納できる。JavaScriptやPythonとも親和性が高い。
このような特徴から、DOMでXMLを操作したり、SQLクエリでデータベースにデータを格納したり、MS-Excelファイルを編集したりする従来のフォーマットから、徐々にJSONへと移行していくものだと思われる。
JSONのサンプルは以下が参考になる。
以下はYouTubeの入門動画。
2025.12.16
以下はGoogleのAIが書いた、C++による簡易的なJSONパーサー。ただし、ネストされたオブジェクトや配列、nullには未対応で、エラーチェックもほぼなし。
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <sstream>
// JSONの値の種類を定義
enum class JsonType { STRING, NUMBER, BOOL, OBJECT };
// JSONの値を格納する構造体(簡易版)
struct JsonValue {
JsonType type;
std::string string_val;
int int_val = 0;
bool bool_val = false;
std::unordered_map<std::string, JsonValue> object_val;
};
// スペースを飛ばす関数
void skipWhitespace(const std::string& json, size_t& pos) {
while (pos < json.length() && isspace(json[pos])) {
pos++;
}
}
// 文字列を解析する関数 ("..."部分)
std::string parseString(const std::string& json, size_t& pos) {
pos++; // '"' を飛ばす
size_t start = pos;
pos = json.find('"', start);
std::string result = json.substr(start, pos - start);
pos++; // '"' を飛ばす
return result;
}
// JSONObjectを解析する関数
std::unordered_map<std::string, JsonValue> parseObject(const std::string& json, size_t& pos) {
std::unordered_map<std::string, JsonValue> object;
pos++; // '{' を飛ばす
skipWhitespace(json, pos);
while (pos < json.length() && json[pos] != '}') {
skipWhitespace(json, pos);
if (json[pos] == '"') {
std::string key = parseString(json, pos);
skipWhitespace(json, pos);
if (json[pos] == ':') {
pos++; // ':' を飛ばす
skipWhitespace(json, pos);
// 値の解析 (簡易的にString, Int, Boolのみ対応)
if (json[pos] == '"') {
object[key] = {JsonType::STRING, parseString(json, pos)};
} else if (isdigit(json[pos]) || json[pos] == '-') {
size_t start = pos;
while (isdigit(json[pos]) || json[pos] == '-') pos++;
object[key] = {JsonType::NUMBER, "", std::stoi(json.substr(start, pos - start))};
} else if (json.substr(pos, 4) == "true" || json.substr(pos, 5) == "false") {
bool b = (json.substr(pos, 4) == "true");
object[key] = {JsonType::BOOL, "", 0, b};
pos += b ? 4 : 5;
}
}
}
skipWhitespace(json, pos);
if (json[pos] == ',') pos++; // ',' を飛ばす
}
pos++; // '}' を飛ばす
return object;
}
int main() {
std::string json = R"({
"name": "John Doe",
"age": 30,
"isStudent": false
})";
size_t pos = 0;
skipWhitespace(json, pos);
if (json[pos] == '{') {
auto data = parseObject(json, pos);
// 結果の出力
std::cout << "Name: " << data["name"].string_val << std::endl;
std::cout << "Age: " << data["age"].int_val << std::endl;
std::cout << "IsStudent: " << (data["isStudent"].bool_val ? "true" : "false") << std::endl;
}
return 0;
}
実行方法:
g++ -std=c++11 simple_json_parser.cpp -o parser ./parser
実行結果:
Name: John Doe Age: 30 IsStudent: false
2026.02.19
以下はGoogleのAIが書いた、C++による簡易的なJSONパーサーその2。ネストされたオブジェクトや配列にも対応したバージョン。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <variant>
#include <optional>
#include <memory>
// JSONのデータ型を定義
struct JsonValue;
using JsonObject = std::map<std::string, JsonValue>;
using JsonArray = std::vector<JsonValue>;
struct JsonValue {
std::variant<std::nullptr_t, bool, double, std::string, std::shared_ptr<JsonObject>, std::shared_ptr<JsonArray>> data;
// ヘルパー: 型チェック
bool is_null() const { return std::holds_alternative<std::nullptr_t>(data); }
bool is_string() const { return std::holds_alternative<std::string>(data); }
bool is_number() const { return std::holds_alternative<double>(data); }
bool is_bool() const { return std::holds_alternative<bool>(data); }
bool is_object() const { return std::holds_alternative<std::shared_ptr<JsonObject>>(data); }
bool is_array() const { return std::holds_alternative<std::shared_ptr<JsonArray>>(data); }
// ヘルパー: 値の取得
std::string get_string() const { return std::get<std::string>(data); }
double get_number() const { return std::get<double>(data); }
bool get_bool() const { return std::get<bool>(data); }
JsonObject& get_object() { return *std::get<std::shared_ptr<JsonObject>>(data); }
JsonArray& get_array() { return *std::get<std::shared_ptr<JsonArray>>(data); }
};
// パーサー本体
class Parser {
std::string json;
size_t pos = 0;
void skip_whitespace() {
while (pos < json.size() && isspace(json[pos])) pos++;
}
char next_char() {
skip_whitespace();
return json[pos];
}
std::string parse_string() {
pos++; // " をスキップ
std::string s;
while (pos < json.size() && json[pos] != '"') {
s += json[pos++];
}
pos++; // " をスキップ
return s;
}
JsonValue parse_value();
JsonValue parse_object() {
auto obj = std::make_shared<JsonObject>();
pos++; // { をスキップ
skip_whitespace();
if (next_char() == '}') {
pos++;
return JsonValue{obj};
}
while (true) {
skip_whitespace();
std::string key = parse_string();
skip_whitespace();
if (json[pos] == ':') pos++;
(*obj)[key] = parse_value();
skip_whitespace();
if (json[pos] == ',') {
pos++;
} else if (json[pos] == '}') {
pos++;
break;
}
}
return JsonValue{obj};
}
JsonValue parse_array() {
auto arr = std::make_shared<JsonArray>();
pos++; // [ をスキップ
skip_whitespace();
if (next_char() == ']') {
pos++;
return JsonValue{arr};
}
while (true) {
arr->push_back(parse_value());
skip_whitespace();
if (json[pos] == ',') {
pos++;
} else if (json[pos] == ']') {
pos++;
break;
}
}
return JsonValue{arr};
}
JsonValue parse_number() {
size_t start = pos;
while (pos < json.size() && (isdigit(json[pos]) || json[pos] == '.' || json[pos] == '-' || json[pos] == '+')) {
pos++;
}
return JsonValue{std::stod(json.substr(start, pos - start))};
}
public:
Parser(std::string j) : json(std::move(j)) {}
JsonValue parse() {
return parse_value();
}
};
JsonValue Parser::parse_value() {
skip_whitespace();
char c = json[pos];
if (c == '"') return JsonValue{parse_string()};
if (c == '{') return parse_object();
if (c == '[') return parse_array();
if (isdigit(c) || c == '-') return parse_number();
if (json.substr(pos, 4) == "true") { pos += 4; return JsonValue{true}; }
if (json.substr(pos, 5) == "false") { pos += 5; return JsonValue{false}; }
if (json.substr(pos, 4) == "null") { pos += 4; return JsonValue{nullptr}; }
return JsonValue{nullptr};
}
// 動作確認用
int main() {
std::string json_str = R"(
{
"name": "John",
"age": 30,
"isStudent": false,
"address": {
"city": "Tokyo",
"zip": "100-0001"
},
"hobbies": ["reading", "coding", {"type": "sports", "name": "soccer"}]
}
)";
Parser parser(json_str);
JsonValue root = parser.parse();
if (root.is_object()) {
auto& obj = root.get_object();
std::cout << "Name: " << obj["name"].get_string() << std::endl;
// オブジェクトのアクセス
auto& addr = obj["address"].get_object();
std::cout << "City: " << addr["city"].get_string() << std::endl;
// 配列のアクセス
auto& hobbies = obj["hobbies"].get_array();
std::cout << "First Hobby: " << hobbies[0].get_string() << std::endl;
std::cout << "Third Hobby Type: " << hobbies[2].get_object()["type"].get_string() << std::endl;
}
return 0;
}
2026.02.20
2026.03.02編集
HOCONはJSONを改良した新しい設定ファイル書式。名前にHuman-Optimizedとあるように、機械ではなく人間にとって記述・編集しやすいように考えられている。
2025.04.24
C++におけるBoost.PropertyTreeについてはC++(STL・ライブラリ)も参照のこと。