データ形式・構造化データ
JSONのエラーは、どこを直せばいい?
使うツール
設定を一つ変えただけなのに、JSONを読み込めなくなった。エラーの行へ移動しても、そこには普通の閉じ括弧しかない。こんなときは、括弧を消したり値を削ったりする前に、読み手がどこで困ったのかを考えてみましょう。
ここでは実運用の設定を使わず、短い例で修正の順序を練習します。目標はエラー表示を消すことだけではありません。元の名前や数値の意味を保ったまま、利用先が読み取れるデータへ戻すことです。
閉じ括弧の前のカンマを見てみよう
JSON整形・検証を開き、次の例だけを入力して実行します。末尾のカンマを含めて貼り付けてください。まず失敗を再現し、その後に一か所だけ直す練習です。
{"name":"Ada","count":2,}countの値の後ろにカンマがあります。カンマがあると、続けて別の項目が来るはずです。しかし、すぐにオブジェクトを閉じる記号が現れます。エラー位置が閉じ括弧付近でも、見直すべきものはその直前の区切りです。
{"name":"Ada","count":2}再実行して整形されたら、nameはAda、countは数値の2のままかを確認します。成功表示だけでなく、修正で残すべき情報が残ったかを見るところまでを一回の作業にします。
一度に全部直さないほうが、早く直せる
長い設定でいくつもエラーが出ると、全部の引用符やカンマを置換したくなります。しかし、一つの引用符の閉じ忘れが、その後の多くの文字を別の意味に変えている場合があります。まず先頭側のエラーから、周囲を数文字ずつ読みます。
- 元のデータを利用者自身の作業用コピーとして残す。
- 最初のエラーと、その直前の引用符・区切り・括弧を確認する。
- 意味を変えない最小限の修正を一つ行い、再実行する。
- 成功後に値と件数を確認し、必要なら修正前後を比較する。
見た目が似た引用符にも注意
{"name":"Ada"}
{'name':'Ada'}
{“name”:“Ada”}最初はJSONの文字列に使う二重引用符です。二つ目は一重引用符、三つ目は文書作成ソフトなどで使う曲がった引用符です。画面では似ていても、同じ文字ではありません。記事やメッセージからコピーして壊れた場合は、ここを疑う価値があります。
ただし、全文の一重引用符を機械的に二重引用符へ置き換えるのは避けましょう。O'Reillyのように値の中の文字である場合もあります。区切りとしての引用符と、文字列の中身を分けて見る必要があります。
エラーを消すために、数字を文字へ変えていない?
{"count":2,"enabled":false}
{"count":"2","enabled":"false"}引用符で囲めば読めるようになったとしても、利用先が数値を要求していれば別の問題になります。文字列のfalseは、真偽値のfalseと同じではありません。整形ツールが成功しても、アプリケーションの入力条件を満たしたとは限らないのです。
反対に、00123という会員番号なら、文字列として先頭のゼロを残す設計が自然なこともあります。見た目が数字かどうかではなく、足し算する量なのか、識別するための名前なのかを確認します。型を変更する前に、受け渡しの仕様へ戻るのが近道です。
整形すると、値ではなく構造が見えてくる
{"items":[{"name":"pen","quantity":2},{"name":"book","quantity":1}],"currency":"JPY"}この例を2文字インデントで整形すると、itemsの下に二つの要素があることを追いやすくなります。nameとquantityは各商品の組で、currencyはその外側です。段差は内容を増やしているのではなく、もともとあった所属関係を見やすくしています。
圧縮へ切り替えると、構造の外側にある余分な空白や改行を減らせます。ただし文字列の中の空白はデータです。名前の中の空白まで消す操作とは違います。読みやすさを優先する作業用には整形、受け渡しサイズを抑えたい場面には圧縮と、目的で使い分けます。
桁数の多いIDは、最後の数字まで照合する
{"id":9007199254740993}この例は、見た目だけの確認をすり抜けやすい失敗を探すためのものです。SheepDevの整形処理は精度を保持するパーサーを使うため、この整数を末尾の3まで保持します。整形後の出力を別の表計算ソフトやプログラムへ渡すときは、そこでも同じ桁を保持できるかを確認してください。
桁が変わったものを後から整形しても、失われた元の桁は復元できません。比較用の原文を残すのは、このためでもあります。数値を文字列に変える対策を採る場合も、利用先の仕様を変更してよいかは別の判断です。
改行や引用符を、値の中へ入れたいとき
{"message":"He said \"hello\".\nNext line."}文章そのものに引用符が入っていると、どこまでが値なのか分かりにくくなります。この例のバックスラッシュは、直後の引用符を文字列の終わりではなく内容として扱うための記号です。また、バックスラッシュとnの並びは、改行を表します。エディター上で見える二つの文字と、読み取った後の改行は別のものです。
実際の改行を文字列の途中へそのまま貼り付けた場合と、この表記を入力した場合を混同しないでください。エラーを避けようとして改行を削除すれば、文章の意味や表示が変わることもあります。整形は表現を読みやすくする操作であり、文章を編集する操作ではないと考えると、修正範囲を決めやすくなります。
貼り付けたものは、本当にJSONだけ?
ログ画面の一行を丸ごとコピーすると、日時やINFOというラベルまで付いてくることがあります。ブラウザーの開発者ツールでは、オブジェクトの説明用表示をコピーしただけの場合もあります。そのまま読めないからといって、APIが壊れているとは限りません。まず、コピー元が実際のレスポンス本文なのか、画面上の見やすい表現なのかを確認します。
チャットや解説記事から取った例には、コードブロックを囲う記号や『入力例』という見出しが混ざることもあります。逆に、最後の括弧までコピーできず、途中で切れていることもあります。本文だけを選び直し、先頭と末尾を確かめてから、内容の修正へ進むと余計な変更を避けられます。
二つのJSONを続けて貼ると、配列になる?
{"id":1}
{"id":2}一つずつなら読めるデータでも、続けて貼ると別の問題になります。JSON Linesなど、一行ずつ別のJSONを扱う形式と、一つのJSON文書は区別してください。SheepDevのJSON整形へ二つの文書をそのまま渡して、自動的にまとめてもらうことはできません。
[{"id":1},{"id":2}]配列にするなら、角括弧と要素間のカンマが必要です。ただし、『エラーが消えるから配列へ変更する』ではなく、受け取る側が配列を求めているから変更します。元が一件ずつ処理するログであれば、その形式のまま扱うほうが正しい場合もあります。文法の修正とデータ構造の変更を分けて考えましょう。
整形できた後に、何を確認する?
JSONとして読めることと、正しい設定であることは別です。例えばquantityが負数でも、キー名をquantitiyと書き間違えても、文法だけなら成立する場合があります。必須項目や値の範囲は、受け取るシステムの仕様と照合します。
修正結果を共有するときは、『整形できました』だけでなく、『末尾のカンマを除き、nameとcountの値は変更していません』のように、変えたものと確認したものを伝えると役立ちます。原因と確認範囲が伝われば、次の人が同じ調査を繰り返さずに済みます。