日本語

開発者ツール · JSON フォーマッタとバリデータ

JSON バリデーターがエラーの正確な行と列を見つける方法

· 仕組み

json 検証 開発者のワークフロー

小さな JSON ドキュメント内の予期しないキーの下にキャレットが配置される
オリジナル ToolAcre ベクトル イラスト

ブラウザ エンジンは JSON.parse エラーの報告方法が異なり、文字オフセットのみを示すものもあります。この投稿では、バリデーターがどのようにしてそれを行と列に変換するのか、また、位置が間違いを犯した場所ではなく解析が停止した場所をマークする理由について説明します。

何も伝えないエラー メッセージ — 「JSON の位置 1432 に予期しないトークンがあります」が 400 行のファイルでは役に立たない理由

「予期しないトークン」などのエラーは、エディターで開くことができる場所を提供しないため、長い構成ではイライラします。 JSON.parse はブラウザーの信頼できるパーサーですが、その診断テキストは JavaScript エンジンとバージョンによって異なります。 ToolAcre は、不安定な英語のエラー文字列と照合して場所を推測しません。 JSON.parse が失敗した場合、別の厳密なスキャナーが元のテキストを調べて、JSON 文法が受け入れられない最初の文字を識別します。

JSON パーサーが読み取り時に実際に行うこと — トークン化と、一度に 1 つの値を消費する再帰降下文法についてのウォークスルー

JSON には 6 つの構造文字 (中括弧、括弧、コロン、カンマ) と、文字列、数値、配列、オブジェクト、true、false、または null の値が含まれます。スキャナは、カンマを区切り文字として呼び出す前に、それが引用符で囲まれた文字列内にあるかどうかを知る必要があります。{"note":"A,B"} の値は 2 つではなく 1 つです。値またはオブジェクトのメンバーをステップスルーして、次に何が合法的に続くかをチェックします。この文法は RFC 8259 で定義されており、JavaScript オブジェクト リテラルとは異なり、コメントや末尾のカンマは許可されません。

文字オフセットから行および列へ — 失敗オフセットまで改行をカウントし、CRLF 末尾とマルチバイト文字がカウントを複雑にする理由

スキャナーは通常、元の JavaScript 文字列のゼロベースのオフセットから始まります。これを有効にするには、オフセットの前の改行を数えて、失敗が最後の改行からどのくらい離れているかを調べます。 CRLF は 2 行ではなく、1 つの視覚的な行末として扱われる必要があります。 JavaScript 文字列内の位置は、ディスク上の UTF-8 bytes ではなく、UTF-16 コード単位をカウントします。非 BMP 絵文字は、1 つのグリフを視覚的に表示するエディターで 2 つのコード ユニットを占有することができます。 UI は行、列、抜粋をレポートするので、貼り付けたファイルに対してキャレットをチェックできます。

解析が停止する場所は間違いがある場所ではありません。カンマの欠落は次のキーで報告され、引用符が迷子になっているとエラーが何行も下に押し出される可能性があります。

最初の不可能なトークンは、最初の間違いの後に発生することがよくあります。オブジェクト内で true の後のカンマを忘れると、次のプロパティの開始引用符が不正になります。パーサーはカンマまたは右中括弧を予期していました。文字列が終了していない場合、後の改行または入力の終わりでエラーが発生する可能性があります。報告されたポイントから逆方向に読んで、欠落している区切り文字を見つけます。キャレットの下の文字を削除する必要があるとは考えないでください。

有効な例: カンマが 1 つ欠落している構成 — 報告された位置、周囲のトークン、および真の原因に逆戻りする方法

リテラルの 3 行ドキュメント {"name":"demo" を試してみてください。続いて 2 行目で "enabled":true、3 行目で "port":8080} が続きます。true の後にはカンマを入れません。 ToolAcre は行 3、列 1、オフセット 31 をレポートします。前のプロパティの後にカンマまたは } が必要であり、「port」の最初の引用符の下にキャレットが表示されます。 2 行目の末尾にカンマを挿入し、再度検証します。これは最初の構文障害の診断であり、「port」という単語が間違っているという判断ではありません。

ブラウザ エンジンの違い — V8、SpiderMonkey、JavaScriptCore は同じ障害を異なる言い方で表現するため、一貫した行と列のレポートが役立ちます

V8、SpiderMonkey、および JavaScriptCore では、同じ JSON.parse エラーに対して異なる表現が使用され、場合によっては異なるコンテキスト スニペットが使用されています。 ToolAcre のスキャナーは、ネイティブ パーサーが値を拒否した場合に、独自の構造的な理由と場所を提供します。スキャナーが JSON.parse と一致しない場合、ツールは位置を作成せずにエンジン エラーを返します。このフォールバックは、自信を持って推測された文字を指すよりも安全です。

これでカバーされないもの — 構文バリデーターがフラグを立てない、間違った型、フィールドの欠落、スキーマ違反などのセマンティックな問題

構文的に有効なオブジェクトであっても、アプリケーションにとっては間違っている可能性があります。必須フィールドの欠落、テキストとして書き込まれた年齢、2 つの重複キー、または存在しないファイルへの参照は、自動的には無効な JSON にはなりません。 RFC 8259 では、相互運用性のためにメンバー名は一意である必要があると述べていますが、単なる解析では API スキーマを強制するものではありません。ここで構文を検証し、ドキュメントを使用するプログラムのセマンティック制約を検証します。

要点: 位置を「文法が受け入れられなかった最初のトークン」として読み取り、JSON フォーマッタとバリデータがテキストをアップロードせずにその行と列をどのように報告するか

報告された位置を「この文法が受け入れられなかった最初のトークン」として扱います。原因を逆算して問題を 1 つ修正し、再実行します。 JSON フォーマッタとバリデータは、貼り付けられた設定をアップロードせずに、これをローカルで実行します。代わりにオフライン エディタでファイルを診断できる場合は、実際の運用認証情報を公開 Web サイトに貼り付けないでください。