Our store doesn't capture in RDF elements containing extension
attributes so yesterday we started climbing this hill in our trek to
Atom/OWL mountain. Ben Szekely, Lee and I were discussing how do we want
to model extensions in a way that was not as structured as Powell's
approach and came up with some good ideas.
Here's the problem child #1:
<a:link rel="replies" href="foo" thr:count="10" xmlns:thr="urn:foo" />
Here's another problem child #2:
<a:id xmlns:x="urn:bar"
x:identifierType="lsid">urn:lsid:ex.org:entries:1</a>
#1 is not that bad:
:link [ a :Link;
:rel iana:alternate ;
:to [ :src <http://example.org/>;] ;
thr:count "10"; # notice JS extension
];
#2 is where the hill got a little steep:
[] :id "urn:lsid:ex.org:entries:1"^^xsd:anyURI .
However, Lee remembered to check the hiking module and found this gem:
http://www.w3.org/TR/rdf-schema/#ch_value
"""rdf:value is an instance of rdf:Property that may be used in
describing structured values."""
There's a note to see example 16 in the RDF primer, but that's not
right. Instead you must go to Section 4.4
http://www.w3.org/TR/2004/REC-rdf-primer-20040210/#rdfvalue
"""in some cases one of the parts of the structured value is often
thought of as the "main" value, with the other parts of the relation
providing additional contextual or other information that qualifies the
main value."""
The most relevant line: "...or other information that qualifies the main
value..."
[] :id [
rdf:value "urn:lsid:ex.org:entries:1"^^xsd:anyURI
# other contextual information..
] .
Now we can go into the extension attributes...
[] :id [
rdf:value "urn:lsid:ex.org:entries:1"^^xsd:anyURI
x:identifierType "lsid" ;
random:property "randomValue" .
] .
x:identifierType rdfs:type atom:extensionAttributeProperty;
atom:extensionAttributeProperty rdfs:subClassOf rdf:Property .
Now because of atom:extensionAttributeProperty we can figure what
extension attributes to attach back to the original element.
Now onto extensions.
atom:extension rdfs:type atom:extensionElementProperty;
<a:entry>
<gd:when startTime="2005-06-06" endTime="2005-06-07"
valueString="This weekend"/>
</a:entry>
[ :extension "<gd:when startTime="2005-06-06" endTime="2005-06-07"
valueString="This weekend" xmlns:gd="http://schemas.google.com/g/2005"
/>"^^rdf:XMLLiteral .
]
Luckily, the only two things we need to pass to extension elements:
xml:lang and xml:base and those can easily be added (unless there's a
conflict, but that's another hill to climb and we're not there yet since
we can only climb on hill at a time).
Now in case someone brings up the I would like to query the name of the
extension (local and/or ns) etc, I would like to push that off to SPARQL
and a XPath extension against the XMLLiteral.
Additionally, we could support :simpleExtension.
<a:entry>
<s:when>Today</s:when>
</a:entry>
[
s:when "Today" .
] .
s:when rdf:type atom:simpleExtensionElementProperty .
atom:simpleExtensionElementProperty rdfs:subClassOf rdf:Property .
Regards,
Ben, Lee and I.
This is exactly the right time to start playing with extensions. I
have not tried at all yet.
(in part because it seems like the most clearly badly designed part
of atom - and the thought of all
this wasted time because ... ok I'll stop the rant right here.)
> [snip]
> <a:link rel="replies" href="foo" thr:count="10" xmlns:thr="urn:foo" />
>
> #1 is not that bad:
>
> :link [ a :Link;
> :rel iana:alternate ;
> :to [ :src <http://example.org/>;] ;
>
> thr:count "10"; # notice JS extension
> ];
is thr:count a real extension btw? Do we have good examples for
this? You probably by now have a list of good extensions.
I suppose in the end we will never be able to formulate a general
rule to know if people put extension there if the extension is meant
to go on the :Link object or on the :Content object it points to.
By the way this could be an argument for making Link just simply
opaque so that all :Link objects always appear like
this
:link [ a :Link;
:href <http://eg.com/e1.html>;
:rel iana:alternate;
:type "text/html";
thr:count "10";
] .
here we would be very close to the syntax.
Of course having something that simplifies things the way we have now
is really nice too. But I am worried that we may be trying to improve
atom.
So keep this in mind as you work with extensions.
> #2 is where the hill got a little steep:
reminder to myself: we are dealing with this example:
<a:id xmlns:x="urn:bar"
x:identifierType="lsid">urn:lsid:ex.org:entries:1</a>
> [snip]
> Now we can go into the extension attributes...
>
> [] :id [
> rdf:value "urn:lsid:ex.org:entries:1"^^xsd:anyURI
> x:identifierType "lsid" ;
> random:property "randomValue" .
> ] .
By the way I wonder how this compares to using owl:sameAs .
[] :id [ owl:sameAs "urn:lsid:ex.org:entries:1"^^xsd:anyURI;
x:identifierType "lsid" ;
random:property "randomValue" ] .
>
> x:identifierType rdfs:type atom:extensionAttributeProperty;
> atom:extensionAttributeProperty rdfs:subClassOf rdf:Property .
>
> Now because of atom:extensionAttributeProperty we can figure what
> extension attributes to attach back to the original element.
ok.
>
> Now onto extensions.
>
> atom:extension rdfs:type atom:extensionElementProperty;
>
> <a:entry>
> <gd:when startTime="2005-06-06" endTime="2005-06-07"
> valueString="This weekend"/>
> </a:entry>
>
>
> [ :extension "<gd:when startTime="2005-06-06" endTime="2005-06-07"
> valueString="This weekend" xmlns:gd="http://schemas.google.com/g/
> 2005"
> />"^^rdf:XMLLiteral .
> ]
Yes. I agree. This is what one has to do, unless one is given some
indication as to the meaning of the extension.
In which case one could process it and extract the meaning as a set
of tri
> Luckily, the only two things we need to pass to extension elements:
> xml:lang and xml:base and those can easily be added (unless there's a
> conflict, but that's another hill to climb and we're not there yet
> since
> we can only climb on hill at a time).
>
> Now in case someone brings up the I would like to query the name of
> the
> extension (local and/or ns) etc, I would like to push that off to
> SPARQL
> and a XPath extension against the XMLLiteral.
>
> Additionally, we could support :simpleExtension.
>
> <a:entry>
> <s:when>Today</s:when>
> </a:entry>
>
> [
> s:when "Today" .
> ] .
>
> s:when rdf:type atom:simpleExtensionElementProperty .
> atom:simpleExtensionElementProperty rdfs:subClassOf rdf:Property .
Yes. That looks good.
> Regards,
Looks like a really good start. Would you like to write up a little
section for the html version explaining this? Perhaps a little
further down the road when things have settled a bit (or before to
help you think about them).
> Ben, Lee and I.
Henry Story wrote:
> On 13 Jul 2006, at 16:38, Elias Torres wrote:
>> As you already know we are putting the final touches on the Atom/RDF
>> store and as we work with James Snell from Abdera and author of many
>> extensions, he found a "bug" as we don't support extension attributes.
>
> This is exactly the right time to start playing with extensions. I
> have not tried at all yet.
> (in part because it seems like the most clearly badly designed part
> of atom - and the thought of all
> this wasted time because ... ok I'll stop the rant right here.)
>
>> [snip]
>> <a:link rel="replies" href="foo" thr:count="10" xmlns:thr="urn:foo" />
>>
>> #1 is not that bad:
>>
>> :link [ a :Link;
>> :rel iana:alternate ;
>> :to [ :src <http://example.org/>;] ;
>>
>> thr:count "10"; # notice JS extension
>> ];
>
>
> is thr:count a real extension btw? Do we have good examples for
> this? You probably by now have a list of good extensions.
As real as it gets.
http://www.ietf.org/internet-drafts/draft-snell-atompub-feed-thread-12.txt
>
> I suppose in the end we will never be able to formulate a general
> rule to know if people put extension there if the extension is meant
> to go on the :Link object or on the :Content object it points to.
>
> By the way this could be an argument for making Link just simply
> opaque so that all :Link objects always appear like
> this
>
> :link [ a :Link;
> :href <http://eg.com/e1.html>;
> :rel iana:alternate;
> :type "text/html";
> thr:count "10";
> ] .
>
> here we would be very close to the syntax.
Sure.
>
> Of course having something that simplifies things the way we have now
> is really nice too. But I am worried that we may be trying to improve
> atom.
Not me.
>
> So keep this in mind as you work with extensions.
>
>
>> #2 is where the hill got a little steep:
>
> reminder to myself: we are dealing with this example:
>
> <a:id xmlns:x="urn:bar"
> x:identifierType="lsid">urn:lsid:ex.org:entries:1</a>
>
>> [snip]
>> Now we can go into the extension attributes...
>>
>> [] :id [
>> rdf:value "urn:lsid:ex.org:entries:1"^^xsd:anyURI
>> x:identifierType "lsid" ;
>> random:property "randomValue" .
>> ] .
>
> By the way I wonder how this compares to using owl:sameAs .
Nothing that I read mentioned owl:sameAs .
http://esw.w3.org/topic/InterpretationProperties
http://www.w3.org/DesignIssues/InterpretationProperties
http://chatlogs.planetrdf.com/rdfig/2003-03-26.html#T18-31-10
k. We'll get to that bridge when we get there. ;)
>
>
>
>> Ben, Lee and I.
>
>
> >
>
The atom namespace for example is: "http://www.w3.org/2005/Atom"
atom:title transformed to a url would be http://www.w3.org/2005/
Atomtitle,
which is a uri, but not really the type we would give the title
attribute in rdf where we would have chosen
the http://www.w3.org/2005/Atom# or http://www.w3.org/2005/Atom/
prefixes. Since those namespaces say nothing about uris we cannot
assume that we can make those uris up that way.
So for example for the thread link extension, we cannot really just
assume that thr:count can be turned into a url by simply appending
"count" to the namespace, as that would give us the url
<http://purl.org/syndication/thread/1.0count>
So my thinking is that we should deal with each extension on an case
by case basis. If we can interpret them we can transform them to rdf,
otherwise we will just have to carry them around as strings. So for
the link example
<a:link rel="replies" href="foo" thr:count="10" xmlns:thr="urn:foo" />
we will have to use
[] :link [ a :Link;
:rel iana:replies ;
:to [ :src <http://example.org/foo>;] ;
:extension "thr:count='10'";
];
Of course as soon as we have an interpreter for this extension, (a
reasonably easy thing to do in this case)
we will be able to agree that the rdf for the link is
[] :link [ a :Link;
:rel iana:replies ;
:to [ thread:count 10;
:src <http://example.org/foo>;] ;
];
This is ugly of course. We need to create a special url for
thread:count, unless the spec writers can agree to one in advance.
But it is the problem inherent in creating a format with no clean
semantics, the way the atom xml has been designed. Luckily, since
atom has no clear semantics, it will be very difficult for extensions
to be developed that will make any sense. The atom working group will
always end up being a huge bottleneck, since extensions that don't
really get approved by that group will not be understood in any clear
manner. So keeping track of extensions and giving them
interpretations should not be such a lot of work.
Of course people dealing with xml databases will find it much easier
to work with atom (atom xml is really designed for
them), since all they will need to do is store the xml file and then
query it with xquery. If new elements are not understood they don't
care. If they later need to make some behavior adapted to the new xml
they will have all the information already available in their database.
Of course people with xml databases will find it very unpleasant to
deal with rdf graphs, even when they are in xml, as those graphs
(unless they have been studiously given the shape of a tree like
RSS1.0 and RSS 1.1 did) will not be very amenable to xquery
questioning. Also any data not in the format of a stable xml tree,
will be completely opaque to those tools. So don't be surprised if
xml database vendors try to make all data take the shape of a tree.
Their whole life depends on it.
Henry Story
So to take the thread example
<a:link rel="replies" href="foo" thr:count="10" xmlns:thr="http://
purl.org/syndication/thread/1.0" />
we can find a url for thr:count by construction quite simply:
http://bblfish.net/work/atom-owl/2006-06-06/ext/http://purl.org/
syndication/thread/1.0/count
We can then create our own prefix
@prefix thr: <http://bblfish.net/work/atom-owl/2006-06-06/ext/http://
purl.org/syndication/thread/1.0#> .
And then we too can write, without fear of trading on someone's toes
[] :link [ a :Link;
:rel iana:replies ;
:to [ :src <http://example.org/foo>;] ;
thr:count 10
];
If these spec writers ever decide on an official rdf url for their
attributes, we can always map our constructed
attributes to theirs using owl:sameAs
thr:coundt owl:sameAs thread:count .
So the trick is to find a good construction mechanism. It would be
very nice if such a construction mechanism on dereferenceing would
return a cgi generated web page explaining the meaning of the
construction.
Henry
let us define two rdf relations
:ElementOrAttribute a owl:Class;
rdfs:comment "the things that group together names and attributes
in xml. There is a name probably, need to look it up. Is it QName?"@en .
:namespace a owl:ObjectProperty;
rdfs:domain :ElementOrAttribute;
rdfs:range xsd:anyUri;
rdfs:comment "The namespace uri for the attribute. For atom xml this
is 'http://www.w3.org/2005/Atom'. We need to create a default uri for
attributes or elements without namespaces."@en.
:name a owl:DatatypeProperty;
rdfs:domain :ElementOrAttribute;
rdfs:range xsd:string;
rdfs:comment "the name of an xml element or attribute. So for
atom:entry the name is 'entry'"@en .
[] cifp:productProperty ( :namespace :name );
a owl:InverseFunctionalProperty .
So we can describe every xml element and attribute with the above
vocab. Eg atom:entry is
_:ae :namespace "http://www.w3.org/2005/Atom"^^xsd:anyUri;
:name "entry" .
Now I suppose we need a vocabulary to map those things to rdf things.
:xml2rdf a owl:ObjectProperty;
rdfs:domain :ElementOrAttribute;
rdfs:range webarch:InformationResource;
rdfs:comment "a property that maps xml syntax elements to
their rdf meaning"@en.
then we can write
_:ae :xml2rdf :entry .
So in particular for thr:count we can write
[] :namespace "http://purl.org/syndication/thread/1.0"^^xsd:anyUri;
:name "count";
:xml2rdf <http://bblfish.net/work/atom-owl/2006-06-06/ext/
http://purl.org/syndication/thread/1.0#count> .
This probably needs some more work, but it looks mostly right.
Henry
[1] On namespace defaulting see also <http://www.w3.org/TR/REC-xml-
names/#defaulting> .