本文へスキップ
AZ Tools

JSON スキーマ検証ツール

左にスキーマ、右にドキュメントを貼り付けると、妥当かどうかと、妥当でないならどこがなぜ駄目なのかを一行ずつ示します。各行にはドキュメント内の JSON ポインター、失敗したキーワード、そのキーワードがあるスキーマ上の位置、問題の値、そしてポインターだけでは分からない「貼り付けた文書の何行目か」が並びます。並び順はファイルを読む順なので、一番上の行がスクロールして最初に出会う問題です。 このツールの要点は anyOf と oneOf の出し方です。多くの検証器は分岐ごとのエラーを一つの平らな一覧に流し込むため、本当に読みたい一文が埋もれます。ここでは失敗は一行のままで、その下に分岐の要約とそれぞれのエラーが付き、問題の数が最も少ない分岐に「最も近い」と印を付けます。たいていそれが書き手の意図した分岐です。oneOf で二つの分岐が同時に通ってしまった場合も、独立した失敗としてどの分岐かを示します。 ドラフトの違いも答えを変えるので、どれを使ったか、それが $schema 由来か選択由来かを表示します。ドラフト 4 では 1.0 は整数ではなく exclusiveMinimum は minimum を修飾する真偽値ですが、ドラフト 6 以降は 1.0 は整数で exclusiveMinimum が境界値そのものです。ドラフト 7 までは $ref の隣に書いたキーワードはすべて無視されます。ドラフトに依らず誤解されやすい規則もあります。required は存在だけを見るので値が null でも満たされ、minLength はコードポイントを数えるので絵文字は 1、結合文字で書いたアクセントは 2、0.3 は二進浮動小数点で 0.1 の倍数ではなく、キーの順序だけが違うオブジェクトは同じ値ですが、順序の違う配列は別の値です。 スキーマ自体が壊れている場合は別の答えになります。型名の綴り違い、配列でない required、コンパイルできない pattern、行き先のない $ref は、ドキュメントの合否ではなくスキーマの不備として位置とともに報告します。 分からないことも明示します。ネットワークにはアクセスしないため URL を指す $ref は解決できず $defs に取り込む必要があり、unevaluatedProperties や unevaluatedItems、$dynamicRef は評価せず注意として示し、2^53 を超える整数は倍精度として読まれ、正規表現は仕様が求めるブラウザのエンジンで動きます。処理はすべてこのページ内で完結し、スキーマもドキュメントも送信されません。

format は既定では注釈にすぎません。エラーにするにはオンにします。

スキーマに $schema があればそのドラフトが使われ、ない場合だけこの設定が使われます。

結果

不正

エラー

7

ドラフト

2020-12

ドキュメント

12 行、169 バイト

エラー 7 件2020-12 · $schema による指定
ドキュメント全体行 1additionalProperties

スキーマは他のプロパティを許可していませんが、次があります: "debug"

debug (行 11)

値: {"name":"","version":"2.1","server":{"host":"0.0.0.0","port":99999,"tls":"yes"},"workers":…

スキーマ: /additionalProperties

/name行 2minLength

文字列はコードポイント 0 個で、最小は 1 個です

値: ""

スキーマ: /properties/name/minLength

/version行 3pattern

"2.1" はパターン ^\d+\.\d+\.\d+$ に一致しません

値: "2.1"

スキーマ: /properties/version/pattern

/server/port行 6maximum

99999 は最大値 65535 を上回ります

値: 99999

スキーマ: /properties/server/properties/port/maximum

/server/tls行 7type

"yes" は string で、スキーマは boolean を求めています

値: "yes"

スキーマ: /properties/server/properties/tls/type

/workers行 9anyOf

anyOf の 2 個の分岐はいずれもこの値を受け付けません

値: 0

スキーマ: /properties/workers/anyOf

分岐ごとの結果

分岐 1 type: integer 問題 1 件最も近い

  • /workers — 0 は最小値 1 を下回ります

分岐 2 const: "auto" 問題 1 件

  • /workers — 0 は定数 "auto" と一致しません
/tags行 10uniqueItems

インデックス 0 と 1 の要素が同じ値です: "a"

値: ["a","a"]

スキーマ: /properties/tags/uniqueItems

すべてこのページ内で処理され、スキーマもドキュメントも送信されません。

使い方

  1. 一つ目の枠にスキーマ、二つ目の枠に検証したいドキュメントを貼り付けます。入力は保存されるのでページを閉じても残ります。
  2. 要約タイルで妥当かどうか、エラー件数、使ったドラフト、ドキュメントの大きさを確認します。ドラフトが $schema 由来か選択由来かも表示されます。
  3. エラー行を上から見ていきます。JSON ポインター、ドキュメントの行番号、失敗したキーワード、そこにあった値、スキーマ上の位置が並ぶので、どちらを直すかすぐ判断できます。
  4. anyOf や oneOf の行では分岐一覧を読みます。「最も近い」と付いた分岐が最も失敗の少ない分岐で、たいていそれが意図したものです。
  5. format を注釈ではなくエラーにしたいときは「format を検証」をオンにします。仕様上 format は注釈なので既定はオフです。

よくある質問

失敗するはずのドキュメントが通るのはなぜですか
たいていはスキーマが見た目ほど多くを言っていないからです。JSON スキーマは知らないキーワードを無視するため、required を require、minLength を minlength と綴り間違えたり、そのドラフトに無いキーワードを書いたりしても、エラーではなく何もしない注釈になります。オブジェクトは additionalProperties が止めない限り余分なプロパティを受け入れ、配列は items や prefixItems が無ければ何でも受け入れ、format は検証をオンにするまで注釈のままです。タイルに出ているドラフトも確認してください。選んだドラフトに無いキーワードはこのツールも無視します。
1.0 は整数ですか
ドラフト 6 以降では整数です。仕様が整数を値で定義するため 1.0 や 1.0e2 は整数で、1.5 は違います。ドラフト 4 では小数点を書いた数は浮動小数点なので "type": "integer" で失敗します。このツールは解析時に数値リテラルの書き方も覚えているので 1 と 1.0 を区別できます。JSON.parse だけでは同じ値になってしまいます。古いライブラリと draft-04 のスキーマを使っているなら、この違いは実際の障害につながります。ドラフトの選択を変えればそのまま再現できます。
なぜ 0.3 は 0.1 の倍数ではないのですか
どちらの値も二進浮動小数点では正確に表せないからです。0.3 を 0.1 で割ると 3 ではなく 2.9999999999999996 になり、参照実装はまさにこの商を調べるのでドキュメントは拒否されます。値を 3 にして multipleOf を 1 と書けば通ります。これはこのツール固有の癖ではなく、python-jsonschema や ajv なども小数の multipleOf では同じ振る舞いをします。「小数点以下二桁」を表したいなら pattern を使うか、セント単位の整数で表すほうが安全です。
エラーの JSON ポインターはどう読みますか
ポインターはドキュメントのルートから始まる、スラッシュ区切りの経路です。/server/port は server オブジェクトの port、/tags/2 は tags の三番目の要素で、添字は 0 から数えます。空のポインターはドキュメント全体を指し、required や additionalProperties、uniqueItems のエラーがメンバーではなくそれを含むオブジェクトや配列を指すのもこのためです。存在しないプロパティには自分の場所がありません。プロパティ名の中の / は ~1、~ は ~0 と書きます。ポインターの横の行番号は、貼り付けた本文でその経路が実際に置かれている行です。
他の検証器で anyOf のエラーが大量に出るのはなぜですか
anyOf が失敗したということはすべての分岐が失敗したということで、そのエラーはどれも事実だからです。構造を与えない検証器はそれらを横並びに出すので、文字列とオブジェクトの和集合では「文字列ではない」という文の隣に、意図もしていないオブジェクトの必須プロパティのエラーが並びます。分岐ごとにまとめれば、スキーマが元から持っていた構造が戻ります。失敗の少ない分岐を選べばたいてい意図した分岐に届きますが、これは証明ではなく推定です。二つの分岐がそれぞれ一つずつ失敗した場合は先のほうに印を付けるだけで、どちらを意図したかはスキーマからは分かりません。
別ファイルや URL を指す $ref も辿りますか
いいえ、意図的に辿りません。ネットワークを使わないので https://example.com/user.json や common.json#/$defs/id のような参照は解決できず、黙って無視せずスキーマの不備として報告します。貼り付けた文書の中の参照は完全に動きます。#/$defs/name、単なる #、ルートへ戻る再帰参照、$anchor、別の参照が名前で呼ぶ $id まで対応します。ファイルに分かれたスキーマを検証したいときは、まず一つにまとめてください。参照先を $defs に入れて経路を書き換えるやり方で、配布前に多くのツールが行っていることでもあります。

関連ツール