Monday, March 14, 2005

ST 2005 Note #2

The problem with the RDF in Note #1 was that we could not constrain the RFD in anyway. A publisher of a movement could add any triples it liked. For many purposes this is not enormously useful.

The last RDF snippet defined was this:

<types:Movement rdf:about="http://www.newco.com/movements/1234">
<terms:carries rdf:resource="http://www.newco.com/grades/5678">
</types:Movement>

<types:Grade rdf:about="http://www.newco.com/grades/5678">>
<terms:name>JET</term:name>
</types:Grade>


What is needed is to ensure that Movement only has one property, carries, and that it can only map to instances of Grade. Imagine we are creating a schema at http://www.newco.com/movements. We'll define each class as an ID within that schema, i.e. a Movement will have URI http://www.newco.com/movements#ID. We also need the namespace for RDF schema.

This means we need to change the namespace of our instance document, and we'll want to reference these namespaces within content so we'll define ENTITY elements as well:

<!DOCTYPE rdf:RDF [
<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
<!ENTITY movements 'http://www.newco.com/movements#'>
<!ENTITY rdfs 'http://www.w3.org/2000/01/rdf-schema#'>
]>
<rdf:RDF xmlns:rdf="&rdf;"
xmlns:movements="&movements;"
xmlns:rdfs="&rdfs;">


We've changed the types namespace so it references IDs - note the trailing #.


xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"

... and the XSD namespace if we reference XSD types.

Anyway, back to the schema definition. Define Movement as a class:

<rdfs:Class rdf:about="&movements;Movement"
rdfs:label="Movement">
<rdfs:subClassOf rdf:resource="&rdfs;Class"/>
</rdfs:Class>


Likewise, let's declare a property carries, ensuring it maps to a grade and is associated with a Movement.

<rdf:Property rdf:about="&movements;carries"
rdfs:comment="Carries relationship mapped to Grade"
rdfs:label="carries">
<rdfs:range rdf:resource="&movements;Grade"/>
<rdfs:domain rdf:resource="&movements;Movement"/>
</rdf:Property>

but we need to ensure Grade is defined:

<rdfs:Class rdf:about="&movements;Grade"
rdfs:label="Grade">
<rdfs:subClassOf rdf:resource="&rdfs;Class"/>
</rdfs:Class>


Now let us define a name property for Grade:

<rdf:Property rdf:about="&movements;name" rdfs:label="carries">
<rdfs:domain rdf:resource="&movements;Grade"/>
<rdfs:range rdf:resource="&xsd;string"/>
</rdf:Property>

We don't have to, but we can also make the fact xsd:string is a datatype explicit thus:

<rdfs:Datatype rdf:about="&xsd;string"/>


One particularly interesting facet is that the properties are defined outside of classes. They are then associated with classes using the rdfs:domain attribute.

However, as the W3C primer notes, RDF doesn't address:

  • cardinality constraints
  • specifying whether a property is transitive
  • specifiying that a property is a unique identifier
  • specifying that two different classes (different URIs) represent the same class., ditto instances.
  • disjoint classes
  • class specific range/cardinality constraints


This is where OWL and other richer schemas come in.