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

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

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

参照用 記事

すごく単純なJSONパス式

JSONデータの一部にアクセスするためのパス式としては、既に JSONPath (http://goessner.net/articles/JsonPath/) や JPath (http://bluelinecity.com/software/jpath) があります。どちらも、XPathのJSON版という位置づけ。これらは便利そうですが、僕の用途にはオーバースペックなので、もっと簡単で小さいな構文を考えてみました。

まず、基本的な構文要素。一部、コメントでお茶を濁してますが、カンベン。

UsualChar ::= {文字列内でエスケープを必要としない印字可能文字}
Escaped ::= {特殊な文字のエスケープ表現}
QuotedString ::= '"' (UsualChar|Escaped)* '"'
NonNegativeInteger ::= '0' | [1-9] [0-9]*
NameStartChar ::= {名前の最初に使える文字、数字は含まれない}
NameChar ::= {名前に使える文字}
Name ::= NameStartChar NameChar*

パス式の構文は次のとおり。

Path ::= '$' | Name
       | Path '.' Name
       | Path '.' NonNegativeInteger
       | Path '[' NonNegativeInteger ']'
       | Path '[' QuotedString ']'

説明と注意:

  1. '$' はデータの「ルート」を表す。JSONPath仕様から拝借。
  2. foo.2 という書き方も許す。これは、foo[2] と同じ。
  3. foo["bar"] という書き方も許す。これは、foo.bar と同じ。
  4. プロパティ名が名前でないときは、foo["hello, world."] のような書き方しかできない。
  5. foo . bar とか foo [ 2 ] と書いても問題は起きないのだが、余分な空白は禁止としておく*1
  6. パス式を文字列データとして書くと、"foo[\"bar\"]" のようになる。まー、しょうがないですね。

次の曖昧性に気がつきます。

  • foo["1"] と foo[1] は同じか?

JSONスキーマでは、object型とarray型は排他的(両方に所属するインスタンスはない)と捉えているようです。foo["1"] はオブジェクト(object型のデータ)に対して適用され、foo[1]は配列(array型のデータ)に対して適用されると考えると、次の解釈が妥当でしょう。

  • foo["1"] と foo[1] は同じではない。

実例を挙げましょう。([追記]JavaScriptでは、foo["1"] == foo[1] なので、そのままJavaScriptの式として解釈はできなくなります。[/追記]

{
 "foo" : { "0": "apple", "1": "orange"},
 "bar" : ["apple", "banana"]
}

上の例に関して:

  1. foo[1] はエラー(構文エラーではなく実行時エラー)
  2. foo.1 はエラー(foo.1 と foo[1] は等価なので)
  3. foo["1"] の値は "orange"
  4. bar[1] の値は "banana"
  5. bar.1 の値は "banana"
  6. bar["1"] はエラー


こんなもんでもけっこう足りるんじゃないのかな。

*1:説得的な必要性があれば、空白を解禁します。