このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

JSONパス形式スキーマ

「すごく単純なJSONパス式」は、いろいろな目的に使う予定でいます。すぐに思いつく用途は、JSONデータの部分(構成要素)へのアクセスです。例えば、次のようなAPIが考えられます。

  • JsonValue get(JsonValue data, String path); // エラー報告は適当に考える
  • void put(JsonValue data, String path, JsonValue value);

それと、「JSONスキーマ、さらに別構文」で述べたスキーマ定義でも使います。この「さらに別構文」についてここで敷衍します。以下で述べるスキーマ構文を「パス形式スキーマ」と呼ぶことにします -- パス(正確にはパスパターン)ごとに型を指定するスタイルだからです。

パスをもっと単純化する

パス形式スキーマ記述で使うために、単純なパスをさらに制限します。


// 余分な空白は入れないとする
Path ::= '$' | Name
| Path '.' Name
| Path '.' NonNegativeInteger

つまり、ブラケットは使わず、オブジェクトのフィールド名は名前に限定します。

この単純化は、スキーマ記述の観点からは特に意味はありません。パス式を、HTMLフォーム内のname属性値として使いたいという事情からの制限です。

ワイルドカード

スキーマ記述では、2種類のワイルドカードが必要になります。

  • '*' -- 任意の名前にマッチする
  • '#' -- 任意の非負整数値にマッチする

例えば、contact.* は、contact.tel, contact.fax, contact.mail などにマッチします。hobbies.# は、hobbies.0, hobbies.1, hobbies.2 などにマッチします。member.#.contact.* のような表現もあります -- このパターンにマッチする例はmember.0.contact.fax, member.2.contact.mail などがあります。

ワイルドカードを含むかもしれないパス式をパスパターンと呼ぶことにします。ワイルドカードを含むパスパターンは、複数のパスを総称的に表すことになります。

パス形式スキーマの書き方


// トークンの間に空白を入れてもよい

スキーマ ::= パス制約 (';' パス制約)*
パス制約 ::= 空 | パス ':' 型仕様

「JSONスキーマ、さらに別構文」では、JSONのフィールド名を意識してパスパターンを二重引用符で囲んでいたけど、うるさいので要らない気がしてきました。

次の例は、平面内の点のリストを表現するデータのスキーマです。


$ : array; // リスト
$.# : object; // 点を表すオブジェクト
$.#.x : integer; // x-座標値
$.#.y : integer; // y-座標値
$.#.color : string?, // 色の名前、名前の正当性はアプリケーションでチェック
default="black";
$.#.state : // 見えているかどうか
enum? ["hidden", "shown"],
default="shown";
$.#.* : any ; // 拡張可能

型を表す名前(string, enum, any)の直後の疑問符「?」は、省略可能性を表します。オリジナルのJSONスキーマでは optional=true というスキーマ属性を使いますが、ここでは、正規表現風に表現します。

$.#.x というパスパターンを見れば、$.# がオブジェクトであること、$が配列であることは推測できるので、$.# と $ に関する記述は省略できます。コメントも省略してコンパクトに書けば:


$.#.x : integer; $.#.y : integer;
$.#.color : string?, default="black";
$.#.state : enum? ["hidden", "shown"], default="shown";
$.#.* : any

セミコロンは終端記号ではなくて分離記号なので、最後のセミコロンは不要ですが、空制約を認めているので、セミコロンをいくら書いても構文エラーにはなりません。スキーマ属性は、カンマで区切って並べて書きます。スキーマ属性の構文/意味はオリジナルのJSONスキーマと同じです。しかし、次の属性は無意味になってしまうので使えません。

  • optional -- 型名に「?」を付ける。
  • additionalProperties -- ワイルドカード「*」を使う。
  • enum -- 属性ではなくてenum型がある
  • options -- 列挙値にラベルが付けられる
  • extends -- 現状、継承は使えない