「マイクロフォーマット(microformats)の蹉跌と希望」において、マイクロフォーマット(microformats)の仕様は曖昧・不明瞭で困ったもんだ、という話をしました。データモデルについても何も書いてありまん。JSONと同じようなもんだろうと思っていたのですが、微妙に違うようです。探しても記述がないので、僕が推測でデータモデルを構成し(でっち上げ)ました。
内容:
基本データ型とプロパティ
基本データ型はたぶん文字列でしょう。しかし、geoフォーマットの経度・緯度の値などは数値が自然です。それと真偽値はあったほうがよさそうなんで、string, number, booleanを基本データ型(スカラー型)とします。
scalar ::= string | number | boolean
型の名前は小文字で書くことにします。対応する集合は最初が大文字の名前で表します。例えばStringは、string型データ・インスタンスの全体です。データインスタンスの集合としては:
- Scalar = String∪Number∪Boolean
ですが、String、Number、Booleanは互いに排他的で、共通部分はないとします。
プロパティ名と呼ばれる文字列と値のペア(順序対)をプロパティと呼びます。プロパティの構文は次のように決めましょう。
property ::= '(' string ':' value ')'
valueの定義は後でします。集合としては:
- Property = String×Value
プロパティのリテラル表記は ("fn" : "檜山 正幸"), ("longitude" : -122.082932) のような形となります(上の構文定義に従う)。
プロパティセットと値
プロパティセットとは、プロパティの有限集合です(まんま)。JSONのオブジェクトと同じようですが、実は違います。プロパティ名が同じ複数のプロパティを許します。例えば次のような:
- {("url" : "http://www.chimaira.org/"), ("url" : "http://d.hatena.ne.jp/m-hiyama/")}
集合ですから、まったく同じ(名前も値も同じ)プロパティが2回出現することはありません(仮に出現しても1回とみなす)。しかし、同じプロパティ名でも値が違うなら何回でも出現できます。
propertySet ::= '{' property* '}' /* 繰り返し('*')は、カンマで区切った並び */
それで、値(value)は次のように再帰的な定義となります。
value ::= scalar | property | propertySet
いろいろと注意事項
定義をまとめておきます。
scalar ::= string | number | boolean
property ::= '(' string ':' value ')'
propertySet ::= '{' property* '}' /* 繰り返し('*')は、カンマで区切った並び */
value ::= scalar | property | propertySet
この定義では、プロパティ名を任意の文字列としていますが、実際には名前は次のパターンに限っているようです。
- [a-z][-a-z0-9]*
この正規表現パターンも事例からの推測で、ほんとのところはわかりません。
空なプロパティセットはどうやら扱わないようです。空集合をマークアップでうまく扱う方法がないので、しょうがないでしょうし、特に必要性もありません。
単一のプロパティからなるプロパティセットは、そのプロパティと同一視するようです。つまり、{("fn" : "檜山 正幸")} は ("fn" : "檜山 正幸") と同じ扱いとなります。すぐ後で示すマークアップ規則では、この同一視は自然です。
マークアップ
マイクロフォーマットでは、マークアップの自由度が非常に高いのですが、考えられる限り一番単純なマークアップ例を示します。
まずスカラー値は、対応する文字列表現にします。プロパティとプロパティセットのマークアップを、テンプレート風の疑似構文で書いてみます。詳しく説明しなくても読めばわかるでしょう。再帰的な定義であることに注意してください。
{* プロパティ (propertyName : propertyValue) *} <div class="{$propertyName}">{ propertyValue をマークアップ変換したもの }</div> {* プロパティセット * {(propertyName1 : propertyValue1), (propertyName2 : propertyValue2), ... } * これを適当な順序で配列とみなす。 *} {foreach from=$propertySet item=prop} {propをマークアップ変換したもの } {/foreach}
例として、次のデータをHTMLマークアップに変換してみます。
("vcard" : {
("fn" : "檜山 正幸"),
("email" : "hiyama{AT}chimaira{DOT}org"),
("url" : "http://www.chimaira.org/"),
("url" : "http://d.hatena.ne.jp/m-hiyama/")
})
次のようになります。
<div class="vcard"> <div class="fn">檜山 正幸</div> <div class="email">hiyama{AT}chimaira{DOT}org</div> <div class="url">http://www.chimaira.org/</div> <div class="url">http://d.hatena.ne.jp/m-hiyama/</div> </div>
JSONへの変換
マイクロフォーマットのデータは、そのままではJSONデータではありません。理由は次の2つです。
そこで次のように対処しましょう。
- 単独のプロパティは、1つだけプロパティを持つオブジェクトにする。
- 同じ名前のプロパティの値を配列としてまとめる。
マイクロフォーマットでは、値とその値だけを含む単元集合を区別しないので、JSON側でも値とその値だけを含む長さ1の配列を区別しなことになります。もとのマイクロフォーマット・データと対応するJSONオブジェクトを並べてみましょう。
("vcard" : {
("fn" : "檜山 正幸"),
("email" : "hiyama{AT}chimaira{DOT}org"),
("url" : "http://www.chimaira.org/"),
("url" : "http://d.hatena.ne.jp/m-hiyama/")
})
{
"vcard" : {
"fn" : "檜山 正幸",
"email" : "hiyama{AT}chimaira{DOT}org",
"url" : ["http://www.chimaira.org/", "http://d.hatena.ne.jp/m-hiyama/"]
}
}
この2つは概念的には異なるデータモデルを持っています(檜山の推測)が、実害が出るほどの違いはないと言えるでしょう。