X-0025 RDFの操作方法の憶え方

自分で書いておきながらすぐ忘れてしまうので、覚え書きです……

RDFは「ツリー構造」ではない

DOM や Web 上のリソースの場合には DOM ツリーやディレクトリ構造といった「各ノード間の固定の親子関係」がありますが、 RDF の場合は、一つのディレクトリ内に全ての HTML リソースをぶち込んでリンクだけで相互に関連付けたような平坦なデータ構造になっています(ツリー状にして関連付けることもできますが、それはあくまで特殊な例です)。各ノード(この例なら個々の HTML リソース)は、データを持っておらず他のノードへのリンクのみを含んでいるタイプと、リンクを含まずデータのみを持っているタイプに分けられ、互いに網目状に結び付けられているという具合にイメージするといいでしょう。なお、個々の RDF データソースは、先の例で言うなら、全ての HTML リソースをぶち込んでいる親ディレクトリそのものにあたります。

「主語・述語・目的語」が操作の基本

この各ノードは「主語、述語、目的語」のような形で関連付けられています。例えばブックマークのセパレータなら、「 ID 名が rdf:#$xA55H1 のリソースの、プロパティ http://www.w3.org/1999/02/22-rdf-syntax-ns#type が指すところは、 http://home.netscape.com/NC-rdf#Separator である」といった具合です。逆に、そのリソースがセパレータであるかどうかが知りたければ、「 ID 名が rdf:#$xA55H1 のリソースのプロパティ http://www.w3.org/1999/02/22-rdf-syntax-ns#type が指すところは何か?」と問えばいいわけです。

nsIRDFDataSource には、これらの操作のためのメソッドが用意されています。どんなメソッドがあるかは IDL 定義を見るのが早いのですが、特によく使うものをいくつか紹介します。

特定のノードへの参照情報を得る

まず、nsIRDFService のメソッドから紹介します。

GetResource(aID)
ID 名が aID のリソースを得る。 ID 名は URI 形式。 DOM で言えば getElementById(aID)あるいはcreateElement(aID)に相当する?
GetLiteral(aString)
内容が aString の文字列リソースを得る。 DOM で言えば createTextNode(aString)に相当する?

これらのメソッドで得られるのは、ノードそのものではなく、そのノードへの参照情報です。XMLのDOMに慣れきっている場合は理解しにくいかもしれませんが、例えば、getElementById()に渡す引数を数値から文字列に手動で変換する必要があるのだ、と考えて下さい。JavaScriptならString()***.toString()を使う所を、RDFの操作ではGetResource()GetLiteral()を使う、という具合です。

RDFの操作では、純粋にgetElementById()などに相当するものはありません。現在のMozillaの実装は、XMLのDOMのようなオブジェクト指向的なアプローチではなく、C言語のような「昔ながらの手続き型処理」的なアプローチを取っています。サードパーティ製のラッパーを使わない場合、この点にはくれぐれも注意が必要です。

参照情報を元に処理を行う

ノードや文字列リソースへの参照情報を得たら、後はそれを使って処理を行うだけです。具体的なデータの操作は個々のデータソースに対して行うもの(冒頭の例でいえば「ディレクトリの中のファイルを削除する」などのような感じ)なので、データソースのメソッドを使うことになります。

以下に、データソースの主要なメソッドを紹介します。なお、変数の引数は全て、前述の方法で得た参照情報です(返り値も参照情報です)。

GetSource(aProperty, aTarget, true), GetSources(aProperty, aTarget, true)
プロパティ aProperty の値がターゲット aTarget を指しているリソースを得る。 XUL の DOM で言えば getElementsByAttribute(aAttrName, aValue)
GetTarget(aResource, aProperty, true), GetTargets(aResource, aProperty, true)
リソース aResource のプロパティ aProperty が指しているターゲットを得る。 DOM で言えば getAttribute(aAttrName)
ArcLabelsIn(aResource)
リソース aResource を何らかのプロパティのターゲットとして参照している全てのリソースを得られる。 DOM で言えば parentNode
ArcLabelsOut(aResource)
リソース aResource の全てのプロパティを得る。 DOM で言えば attributeschildNodes
Assert(aResource, aProperty, aTarget, true)
リソース aResource に、プロパティ aProperty と、そのターゲット aTarget を関連付ける。属性名と値が一対一の「属性」と違って、同じプロパティ名に複数のターゲットを関連付けられるので、注意がいる。 DOM で言えば appendChild(aNode), insertBefore(aNode, aReference)
Unassert(aResource, aProperty, aTarget)
リソース aResource からプロパティ aProperty ・ターゲット aTarget への関連付けを取り除く。 DOM で言えば removeChild(aNode)