4

RDF does not forbid you to have multiple objects referred via the same subject/predicate pair. In other words, something like this is allowed

<http://example.com/foo> <foaf:knows> <http://example.com/bar>
<http://example.com/foo> <foaf:knows> <http://example.com/quux>

However, you could obtain the same result by enforcing subject/predicate uniqueness and connect to a Seq node

<http://example.com/foo> <foaf:knows> <_:id>
<_:id> <rdf:type> <rdf:Bag>
<_:id> <rdf:_1> <http://example.com/bar>
<_:id> <rdf:_2> <http://example.com/quux>

What are the advantages/disadvantages of the two approaches, and is there an authoritative preference ?

flag

3 Answers

5

Personally I would always prefer the first approach. The very essence of RDF is it's open-worldness - the ability to state as many facts about something as you wish and to be completely contradictory. If you have an application where you need cardinality constraints then you are likely going to need to use OWL

Also the first approach has the advantage that it's potentially much easier to retrieve all the values for a given subject predicate pairing (depending on the API used) though I'd expect the first form to be easier to traverse in most APIs.

Pseudo-code(ish) examples
Approach 1

foreach (Triple t in g.GetTriplesWithSubjectPredicate(<http://example.com/foo>,"foaf:knows")
{
    //Do whatever you want with each value
}

Approach 2

foreach (Triple t in g.GetTriplesWithSubjectPredicate(<http://example.com/foo>,"foaf:knows")
{
    if (t.Object is BlankNode) {
        //Then you have to check whether this thing is a Bag
        //Then if it's a Bag you need another loop to retrieve it's contents
    }
}
link|flag
3

I agree with Rob. Another point is, that the 2nd approach works with a blank node. This can often cause problems later on, as ids for blank nodes are only guaranteed to be unique within one triple store, so you can not work with these nodes outside the triplestore, whereas there is no such problem with the first solution.

link|flag
can't you assign the rdf:type rdf:Bag to a non-blank node to solve the id problem ? – Stefano Borini Jan 22 at 7:39
sure, but still you need a mechanism/algorithm which produces the URI for this node. so you may have to change your business logic to fit this, although this part does not really belong there (i had a similar problem with blank nodes in a project, which gave us a lot of headaches). – Bastian Spanneberg Jan 22 at 11:04
3

There is no authoritative preference in that the W3C didn't say anything on the topic (AFAIK). But in the community the RDF containers vocabulary (rdf:Bag, rdf:Alt and rdf:Seq) is widely seen as obsolete since it doesn't really add any value but rather makes things just more complicated. In fact some have proposed to mark it as deprecated in future revisions of RDF (see current discussion on that topic).

If you don't need order, just use multiple triples with the same predicate. If you do need order then use the RDF collection vocabulary (rdf:List) instead. It lets you do closed lists, you could also do trees with it and it's easier to add something in the middle of it without having to re-number all the predicates. As for querying with order, you can't query lists with SPARQL (yet) - probably easier with the containers.

link|flag

Your Answer

Get an OpenID
or

Not the answer you're looking for? Browse other questions tagged or ask your own question.