javascriptでJSONを読む
2023-11-26 記載
概要 : JSONを読んで中身を扱えるようにします。
Keyword : JSON, javascript, XMLHttpRequest, FileReader,
javascriptは書き方がいろいろあるので、Webでサンプルをみても2つと同じものがない感じです。とくにイベントや無名関数の書き方が多種あってわかりにくいです。宣言していない変数名が登場したり、同期非同期の=>でつなぐパイプライン的処理など、理屈では読みとけないソースです。
無名関数はなるべく使わない。同期が一瞬なら同期にする。不要な変数は受け取らない。変数を使うときは変数名は明瞭につける。という方針で、自分なりに納得できるコードを作成しました。
まずWebから取得のコード。fetchではなくXMLHttpRequestにしています。
htmlボタンClickで下のpreにJSON内容を出力します。
<input type="button" value="JSON" onclick="getJSON_Http()"/>
<pre id="jsonHttp" style="border:solid;"></pre>
function getJSON_Http() {
const xhr = new XMLHttpRequest();
xhr.open("GET", "./chatgpt.json", false); // false=非同期
xhr.setRequestHeader('Cache-Control', 'no-cache');
xhr.send();
var text = xhr.response;
for (var [key, value] of jsonToMap(JSON.parse(xhr.response))) {
text += "\r\n" + key + " : " + value;
}
document.getElementById("jsonHttp").innerText = text;
}
次にニーズは少ないかもしれませんがローカルからJSONファイルを読み込むコード。Firefoxでは
import jsondata from ‘./myfile.json’ assert {type: ‘json’};
はErrorになるので、このFileReaderを使う代替手段があります。
<input type="file" onchange="getJSON_File(this)"/>
<pre id="jsonFile" style="border:solid;">.jsonを選択</pre>
function getJSON_File(target_input) {
const reader = new FileReader();
reader.addEventListener("load", () => {
var text = reader.result;
for (var [key, value] of jsonToMap(JSON.parse(reader.result))) {
text += "\r\n" + key + " : " + value;
}
document.getElementById("jsonFile").innerText = text;
});
reader.readAsText(target_input.files[0]);
}
forの3行はコメントアウトしても問題ありません。JSONデータをMapに格納するfunctionを呼んでいます。再帰関数なのでわかりにくいです。
function jsonToMap(json_object, prekey = "", mapItem = new Map()) {
for(var key in json_object) {
if (Array.isArray(json_object[key])) {
for (var i = 0; i < json_object[key].length; i++) {
jsonToMap(json_object[key][i], prekey + "/" + key + "[" + i + "]", mapItem);
}
} else if (typeof json_object[key] == "object") {
jsonToMap(json_object[key], prekey + "/" + key, mapItem);
} else {
mapItem.set(prekey + "/" + key, json_object[key]);
}
}
return mapItem;
}
ChatGPT3.5にサンプルデータを作ってもらいました。
注文:
JSONデータのサンプルを作成してください。2段階のネストがあること。配列も使っていること。
回答:
もちろんです。以下は2段階のネストと配列を含むJSONデータの例です。
この例では、students
というキーがあり、その配列に学生の情報が含まれています。各学生はid
、name
、age
、courses
というキーを持ち、courses
内には複数の科目が配列として含まれています。
{
"students": [
{
"id": 1,
"name": "田中太郎",
"age": 20,
"courses": [
{
"course_id": 101,
"course_name": "数学"
},
{
"course_id": 102,
"course_name": "物理学"
}
]
},
{
"id": 2,
"name": "山田花子",
"age": 19,
"courses": [
{
"course_id": 103,
"course_name": "化学"
},
{
"course_id": 104,
"course_name": "生物学"
}
]
}
]
}
「もちろんです。」とな?
preのinnerTextは以下のように出力されます。Http,Fileのどちらでも。
{
"students": [
{
"id": 1,
"name": "田中太郎",
"age": 20,
"courses": [
{
"course_id": 101,
"course_name": "数学"
},
{
"course_id": 102,
"course_name": "物理学"
}
]
},
{
"id": 2,
"name": "山田花子",
"age": 19,
"courses": [
{
"course_id": 103,
"course_name": "化学"
},
{
"course_id": 104,
"course_name": "生物学"
}
]
}
]
}
/students[0]/id : 1
/students[0]/name : 田中太郎
/students[0]/age : 20
/students[0]/courses[0]/course_id : 101
/students[0]/courses[0]/course_name : 数学
/students[0]/courses[1]/course_id : 102
/students[0]/courses[1]/course_name : 物理学
/students[1]/id : 2
/students[1]/name : 山田花子
/students[1]/age : 19
/students[1]/courses[0]/course_id : 103
/students[1]/courses[0]/course_name : 化学
/students[1]/courses[1]/course_id : 104
/students[1]/courses[1]/course_name : 生物学
前半がChatGPTコードと同じになるのは当たり前といえば当たり前。
([Object, Object]になってうんざりしていたのに↑こう云ってのける)
後半の
/students[0]/id : 1
……
/students[1]/courses[1]/course_name : 生物学
はMapから読みだしたものです。