次のような、述語「x:category」の存在が期待できるRDFにて、カテゴリ名(x:category)がリテラル「XSLT」であるノード集合を特定したいとします。このとき、ルート要素rdf:RDFをコンテクストノードとするなら、XPathのロケーションパスでは次のように表現できます。
<rdf:RDF>
<rdf:Description rdf:about="foo.xml">
<x:category>XSLT</x:category>
</rdf:Description>
<rdf:Description rdf:about="bar.xml">
<x:category>CSS</x:category>
</rdf:Description>
</rdf:RDF>
descendant::rdf:Description[boolean(child::x:category[string(self::*) = 'XSLT']) = true()]
しかしこれは決定的に駄目です。第一に、x:categoryはプロパティ要素であるとは限りません。次のように属性で表現されているかもしれません。この場合、このロケーションパスは何の役にも立ちません。
<rdf:Description rdf:about="foo.xml" x:category="XSLT" />
もう一つのロケーションパスと共に和集合を作ることで解決できなくもありませんが、毎度そのようなXPath式を記述するのは面倒ですし、まだ他にもRDF/XMLの構文を満たしつつ同じ意味を持つ書き方があります。
第二に、このロケーションパスは「カテゴリ名がXSLTであるノード」を表しているものではなく、単に「string-valueが"XSLT"であるx:category要素の集合」を表現しているに過ぎません。しかし、意味に基づいたXPathを書ければ問題は起こらない筈です。
しかしXPath 1.0はRDFなんて知りませんから、独自拡張関数をこしらえる必要があります。
「カテゴリ名がリテラル"XSLT"であるノード」、これを言いかえると、「述語がx:category(QName)で目的語がリテラル"XSLT"となっている主語」です。
ex:getSubject('x:category', 'XSLT')
例えばこのような、第一引数に述語のQName、第二引数に目的語を指定することで主語となっているノードを返却する関数を拡張する手があります。
実装にもよると思いますが、実際には引数にコンテクストノードを渡す必要があったり少々面倒です。
ex:getSubject(., 'x:category', 'XSLT')
第一引数をarg1としますと、arg1.ownerDocument
でソース文書のDocument
を参照するためです。
ただ、QNameを使っている、つまり名前空間接頭辞に依存している点がどうにも納得いかないので試行錯誤中です。