W3C home > Mailing lists > Public > semantic-web@w3.org > August 2007

Re: RDF's curious literals

From: Story Henry <henry.story@bblfish.net>
Date: Wed, 1 Aug 2007 22:26:10 +0200
Message-Id: <8FB28A47-2374-4752-8036-64E23076C280@bblfish.net>
Cc: Semantic Web <semantic-web@w3.org>
To: Garret Wilson <garret@globalmentor.com>

Ok, I think we are getting somewhere here.

The problems you describe below is a problem of the java library  
perhaps building too literal a model of the RDF model. I found  
working with these triples objects annoying when using either Sesame  
or Jena, so I developed so(m)mer


which allows me to annotate java objects and fields with @rdf(uri)  
annotations, and then I can work with normal java objects without  
having to think about these things in the background.

Since we agreed that

123 a :Integer;
     xsd:integer "123";
     = "123"^^xsd:integer ;
     = <http://numbers.com/you/123> .

There is really nothing stopping anyone creating a library that would  
return URIs only, and so avoid
you some of the trouble you describe. Though I would of course prefer  
that it return me a java int, which works better with the rest of the  
java code: do I really want to then write a regular parsing  
expression to parse the URI returned? No. Give me an int.

On 1 Aug 2007, at 21:32, Garret Wilson wrote:

>> Can you let us know how this is causing you any trouble?
> Let's say I use my RDF library in JAVA to read in some N3:
> RDFProcessor rdfProcessor=new RDFProcessor();
> RDFDataModel rdf=rdfProcessor.process(new FileInputStream("my.n3"));
> Then I find all the books in the data model:
> Resource[] books=rdf.getResourcesByType("eg:Book");
> Which is maybe a convenience method for this:
> Resource[] books=rdf.getResourcesByPropertyValue("eg:Book",  
> "rdf:type");
> So if I call books[0].getProperty("rdf:type"), it gives me  
> "eg:Book". No problem.
> So what if I call books[0].getProperty("dc:title").getProperty 
> ("rdf:type")? It doesn't give me anything, because the object of  
> the first book's rdf:title property is not a resource---well, RDF  
> says (hands waving) that it's a resource, but it treats it  
> differently from other resources, making it some strange  
> rdfs:Literal thingy. I want to call books[0].getProperty 
> ("dc:title").getProperty("rdf:type") and get "xsd:Integer", just  
> like other resources.

in this case you mean "xsd:string" or something.

In Sesame this works like this (from memory)

Literal title = model.getStatements(book,URI.create(dc 
if (!title.getLiteralType().equals(xsdstring)) System.exit();

Anyway you are right this is tedious to code to.

In Sommer I would have something like

class Book {

    @rdf(eg+"title") String title;
    @rdf(eg+"pages") int pages;
    @rdf(eg+"author) Person p;


Then I can just do

Collection<Book> bks = model.getAllObjectsOfType(Book.class);

while(Book b: bks) {
    System.out.println("title:"+b.title );
    assert (b.title instanceof String);

So that's a lot simpler of course.

Just as you told me that you don't need to worry about the way the  
data is stored in the DB, so you don't
need to build really clumsy OO mapings to the theoretical model.

> So let's take that further. Let's get the number of pages of the book.
> Resource bookPageCount=books[0].getProperty("eg:pageCount");
> So now I have the book's page count. The page count is a resource--- 
> so RDF would tell you. But really, I have to do something like this:
> if(bookPageCount instanceof Literal)
> {
>  //do something if the resource is a literal
> }
> else
> {
>  //do something if the resource is a non-literal resource
> }

Well that's part of why in OWL it is good to specify the domain more  
precisely, then you know by
definition of the relation that the value of the realtion is going to  
be an int.

Anyway in so(m)mer it's as simple as


> This is just crazy. And unnecessary.
> And it just gets worse from here. Let's say that I want to get all  
> the books in the data model with an author of <http://example.com/ 
> us/presidents/GeorgeWBush>. That's easy:

In so(m)mer I use query by example. So you can do

Book b = new Book();
b.author = new Person("Bush","George");

Collection<Book> results = model.getAllObjectsThatMatch(b);

> Resource[] books=rdf.getResourcesByPropertyValue("dc:author",  
> URI.create("http://example.com/us/presidents/GeorgeWBush"));
> But how do I get all the books with exactly 100 pages? Well, if RDF  
> were consistent, I could do the same thing:
> Resource[] books=rdf.getResourcesByPropertyValue("eg:pageCount",  
> URI.create("http://example.com/integers/100"));
> But I can't do that. Why? Because "100" is a literal. So? Isn't it  
> a resource as well? Well, yes---sort of.
> So let me make it easier. Let me just get all the books authored by  
> resource of type foaf:Person:
> Resource[] books=rdf.getResourcesBySubPropertyValue("dc:author",   
> "rdf:type", "foaf:Person");
> No problem. Whee! This is easy. So now let's find all the books  
> with page counts of type xsd:Integer:
> Resource[] books=rdf.getResourcesBySubPropertyValue 
> ("eg:pageCount",  "rdf:type", "xsd:Integer");

If you use an inferencing database you would probably use some  
interface where you can use a SPARQL query btw.

> What? I can't do that? But isn't 100 a resource, too? Shouldn't it  
> have an rdf:type, just like any other resource? Why do I have to  
> treat it differently?
> The treatment of literals in RDF is a pain, it is strange, it is  
> inconsistent, and it is completely unnecessary. This is a problem  
> with the RDF model---the way that RDF characterizes the world---and  
> only changing the RDF model will fix the problem.
Received on Wednesday, 1 August 2007 20:26:18 UTC

This archive was generated by hypermail 2.4.0 : Tuesday, 5 July 2022 08:45:02 UTC