today | current | recent | random ... categories | search ... who ... syndication

Tuesday, May 18 2004

My Canada XIncludes RDF

Assuming all the boring namespace setup, consider the following chunk of RDF to describe a person and their phone numbers:

<rdf:Description rdf:about = "x-urn:aaronstraupcope:knows:who:~foobar">
 <rdf:type rdf:resource = "http://xmlns.com/foaf/0.1/Person" />
 <vcard:TEL>
  <rdf:Bag>
   <rdf:li rdf:parseType = "Resource">
    <rdf:type rdf:resource="http://www.w3.org/2001/vcard-rdf/3.0#home"/>
    <dc:identifier rdf:resource = \
       "x-urn:aaronstraupcope:knows:phone-number:~123.456.7890" />
   </rdf:li>
  </rdf:Bag>
 </vcard:TEL>
</rdf:Description>

Similarly, consider a second chunk of RDF to describe an organization and it's phone numbers:

<!-- observant readers will note that this is not really
     a list of phone numbers and that if it was the
     code used to query it (below) would fail. but that's
     just syntax and doesn't change the fundamental point -->

<rdf:Description rdf:about = "x-urn:aaronstraupcope:knows:who:~workplace">
 <rdf:type rdf:resource = "http://xmlns.com/foaf/0.1/Org" />
 <vcard:TEL rdf:parseType = "Resource">
  <rdf:type rdf:resource="http://www.w3.org/2001/vcard-rdf/3.0#work"/>
  <dc:identifier rdf:resource = \
     "x-urn:aaronstraupcope:knows:phone-number:~555.555.1212" />
 </vcard:TEL>
</rdf:Description>
 

So, if it's known that :~foobar works at :~workplace it stands to reason that there's no reason to write the same thing twice. Rather, the correct approach would be to reference the latter's work phone number in the former's work phone definition.

There doesn't appear to any way to do this RDF; specifically to reference a discreet subset of another resource's properties. I was able to find a proposal descrbing a fragment identifier syntax [in] RDF but it is only a proposal and already three years old.

More importantly, my own needs for this kind of data involve being able to process it with XSLT. No, I haven't had a sudden change of heart about RDF/XML, but judicious use of xsl:template match = "..." has made it suck just a little less.

Enter XInclude. The following is valid RDF that doesn't really help you connect the dots in a directed graph context but since you can't do that anyway, it doesn't cost you anything either. On the other hand it makes managing, and rendering, disparate but related pieces of data easier.

<rdf:li rdf:parseType = "Resource">
 <xi:include xi:href  = "x-urn:aaronstraupcope:knows:who:~workplace"
             xi:xpointer = "xmlns(r=http://www.w3.org/1999/02/22-rdf-syntax-ns#) \
                            xmlns(f=http://xmlns.com/foaf/0.1/)xpointer(*// \
                            r:Description/r:type[@r:resource= \
                            'http://xmlns.com/foaf/0.1/Org']/following-sibling::* \
                            [name()='vcard:TEL']/r:type[@r:resource= \
                            'http://www.w3.org/2001/vcard-rdf/3.0#work']/parent::*/ \
                            child::*)" />

 <!-- I am still trying to figure out why IsaViz spazzes out
      when I add a xi:fallback directive -->

</rdf:li>

You may want to poke your eyes out after looking at that for too long but, then, nothing's for free and it's the kind of hairiness that could fairly easily be hidden by a GUI client. It goes without saying that the query itself could be optimized.

If, like me, you are using URNs as URIs you'll need to add corresponding rewriteSystem entries in your catalog.xml file so that the XInclude processor is able to resolve the path to the resource you're pointing to.

<rewriteSystem systemIdStartString="x-urn:aaronstraupcope:knows:who:~"
                   rewritePrefix="file:///path/to/you/know/who/" />

Later: the following fixes the bugs described above and doesn't care whether or not phone numbers are wrapped in a rdf:Bag container. It also makes sure that only telephone numbers for a specific resource are included, in case there are multiple resources defined in a single document:

<xi:include xi:href  = "x-urn:aaronstraupcope:knows:who:~workplace"
            xi:xpointer = "xmlns(a=x-urn:aaronstraupcope:knows:who:~') \
                           xmlns(r=http://www.w3.org/1999/02/22-rdf-syntax-ns#) \
                           xmlns(f=http://xmlns.com/foaf/0.1/) \
                           xpointer(*//r:Description[@r:about= \
                           'x-urn:aaronstraupcope:knows:who:~workplace' \
                           ]/child::*[namespace-uri()= \
                           'http://www.w3.org/2001/vcard-rdf/3.0#' \
                           and local-name()='TEL']/descendant-or-self::*/ \
                           r:type[@r:resource='http://www.w3.org/2001/vcard-rdf/ \
                           3.0#work']/parent::*/child::*)" />
 

meta

“Medicine and Health” are on first, today.

 

refers to

meta

[x]

permalink

http://www.aaronland.info/weblog/2004/05/18/5491

pubdate

http://www.aaronland.info/weblog/2004/05/18

created

2004-05-18T12:33:04-04:00

last modified

2004-05-18T17:44:52-04:00

revision

1.6

changes

http://www.aaronland.info/weblog/2004/05/18/5491/changes.html

license

http://creativecommons.org/licenses/by-nd-nc/1.0/

external links

[x]
 
 
Monday, May 17 2004 ←  → Wednesday, May 19 2004