microformats2-parsing-rdf: Difference between revisions

From Microformats Wiki
Jump to navigation Jump to search
(explaining how to handle mixtures of microformats2 and RDFa)
m (tidy)
 
(11 intermediate revisions by 3 users not shown)
Line 1: Line 1:
Draft Microformats2-to-RDF mapping
Below is a proposed mapping of the microformats2 data model to RDF.
 
Tantek asked me to draft up a Microformats2-to-RDF mapping. It's pretty straightforward to do. This is rough and will need cleaning up.


== RDF model ==
== RDF model ==
Line 28: Line 26:
If the element which has the root class name for a microformats2 object also has an about attribute, that SHOULD be used to set the subject for the microformat.
If the element which has the root class name for a microformats2 object also has an about attribute, that SHOULD be used to set the subject for the microformat.


If the element does not have an about attribute, or the HTML processor does not support parsing about attributes, then the subject for the microformat should be an RDF blank node.
If the element does not have an <code>'''about'''</code> attribute, or the HTML processor does not support parsing <code>'''about'''</code> attributes, then the subject for the microformat should be an RDF blank node.


If a parser is also parsing RDFa, it should use the same blank nodes as the subjects for microformats2 objects as it does for statements expressed in RDFa. Given this HTML:
If a parser is also parsing [[rdfa|RDFa]], it should use the same blank nodes as the subjects for microformats2 objects as it does for statements expressed in RDFa. Given this HTML:


<source lang="html4strict">
<source lang="html4strict">
<div class="h-card p-fn" typeof="foaf:Person" property="foaf:name">Tom Morris</div>
<div class="h-card p-name" typeof="foaf:Person" property="foaf:name">Tom Morris</div>
</source>
</source>


Line 41: Line 39:
_:a a uf:h-card, foaf:Person;
_:a a uf:h-card, foaf:Person;
   foaf:name "Tom Morris";
   foaf:name "Tom Morris";
   uf:p-fn "Tom Morris";
   uf:p-name "Tom Morris";
   rdfs:label "Tom Morris" .
   rdfs:label "Tom Morris" .
</source>
</source>
Line 49: Line 47:
<source lang="text">
<source lang="text">
_:a a uf:h-card;
_:a a uf:h-card;
   uf:p-fn "Tom Morris";
   uf:p-name "Tom Morris";
   rdfs:label "Tom Morris" .
   rdfs:label "Tom Morris" .


Line 58: Line 56:
== Representing root class names ==
== Representing root class names ==


Root class names map neatly to RDF's type mechanism. In Notation3, this is represented with the shorthand "a".
Root class names map neatly to <code>'''rdf:type'''</code>. In Notation3, this is represented with the shorthand <code>'''a'''</code>.


<source lang="html4strict">
<source lang="html4strict">
Line 68: Line 66:
</source>
</source>


This is compatible with the RDF specification, but differs from RDF best practice. As with Java and most programming languages, in RDF, it is a custom to capitalize class names.
This is compatible with the RDF specification, but differs from RDF best practice. As with Java and most programming languages, in RDF, it is customary to capitalize class names.


=== Representative hCard parsing ===
== Representing properties ==
(I'm not sure if Microformats2 has representative hCard as a pattern anymore. If not, disregard this section.)
 
Once we have inferred the class name, we need simply declare the properties.
 
For each <code>'''p-'''</code> prefixed property, an RDF statement should be produced with the subject being that of the microformats2 object, the property being the namespaced microformats property, and the object being either a plain literal or a language literal containing the string representation of the object (see language section below). This should be equal to the string value in the JSON output.


If the parser is able to infer that a representative hCard is present on the page, one can represent this by explicitly linking the page to the subject an appropriate property URI from a pre-existing ontology.
=== Multiple properties ===
If there are multiple instances of a property, this should result in multiple statements using the same property name.


TODO: either foaf:primarySubjectOf (or whatever), or something from SIOC, or perhaps Dublin Core to go from the document URI to the bnode or subject URI.
This example hCard contains two category properties and two URL properties:


== Representing properties ==
<source lang="html4strict">
<div class="h-card">
  <img class="u-photo" alt="photo of Mitchell"
      src="https://webfwd.org/content/about-experts/300.mitchellbaker/mentor_mbaker.jpg"/>
  <a class="p-name u-url"
    href="http://blog.lizardwrangler.com/"
    >Mitchell Baker</a>
(<a class="u-url"
    href="https://twitter.com/MitchellBaker"
    >@MitchellBaker</a>)
  <span class="p-org">Mozilla Foundation</span>
  <p class="p-note">
    Mitchell is responsible for setting the direction and scope of the Mozilla Foundation and its activities.
  </p>
  <span class="p-category">Strategy</span>
  <span class="p-category">Leadership</span>
</div>
</source>
 
<source lang="text">
_:lizardwrangler a uf:h-card;
  uf:u-photo <https://webfwd.org/content/about-experts/300.mitchellbaker/mentor_mbaker.jpg>;
  uf:p-name "Mitchell Baker";
  rdfs:label "Mitchell Baker";
  uf:u-url <http://blog.lizardwrangler.com>;
  uf:u-url <https://twitter.com/MitchellBaker>;
  uf:p-org "Mozilla Foundation";
  uf:p-note "Mitchell is responsible for setting the direction and scope of the Mozilla Foundation and its activities.";
  uf:p-category "Strategy";
  uf:p-category "Leadership" .
</source>
 
(In Notation3, it is possible to use commas as a shorthand form to represent multiple statements. This has been avoided in order to better illustrate the point in question.)


Once we have inferred the class name, we need simply declare the properties.
To convert from RDF to JSON, one should take all statements that have the same subject and property and group them together into an array.


=== Language ===
=== Language ===
RDF allows three types of literal: plain literals, language literals and typed literals.
RDF allows three types of literal: plain literals, language literals and typed literals.


Typed literals contain a datatype annotation, language literals contain a language annotation (the same ISO country codes as is used in HTML's lang attribute and XML's xml:lang attribute).
Typed literals contain a datatype annotation, language literals contain a language annotation (the same ISO country codes as is used in HTML's <code>'''lang'''</code> attribute and XML's <code>'''xml:lang'''</code> attribute).


Processors should work out the language tag (if any) of the elements containing microformat properties (using the latest RDFa specification) and emit language-tagged literals for p- prefixed properties. If no language tag is set in the HTML, emit plain literals for all p- prefixed properties.
Processors should work out the language tag (if any) of the elements containing microformat properties (using the latest RDFa specification) and emit language-tagged literals for p- prefixed properties. If no language tag is set in the HTML, emit plain literals for all p- prefixed properties.
For instance:
<source lang="html4strict">
<div class="h-card p-name" lang="ja">内閣総理大臣</div>
<div class="h-card p-name" lang="he">בִּנְיָמִין נְתַנְיָהוּ</div>
</source>
<source lang="text">
_:a a uf:h-card;
  uf:p-name "内閣総理大臣"@ja .
_:b a uf:h-card;
  uf:p-name "בִּנְיָמִין נְתַנְיָהוּ"@he .
</source>


=== rdfs:label ===
=== rdfs:label ===
It is generally good practice for each resource to have an rdfs:label property. This maps to p-name.
It is generally good practice for each resource to have an rdfs:label property. This maps to p-name.


In Notation3 rules:
Using Notation3 rules syntax:


<source lang="text">
<source lang="text">
@forall
@prefix log: <http://www.w3.org/2000/10/swap/log#> .
{ ?s uf:p-name ?o . } => { ?s rdfs:label ?o . } .
@forall ?s ?o .
{ :s uf:p-name :o . } log:implies { :s rdfs:label :o . } .
</source>
</source>


Line 144: Line 195:


== Mapping ==
== Mapping ==
:''See also'': [[microformats2-rdf-mapping]]


The RDF semantics of an hCard can be declared as an RDF document available from microformats.org. This can be used by RDF-minded parsers to draw inferences. In the case of hCard...
The RDF semantics of an hCard can be declared as an RDF document available from microformats.org. This can be used by RDF-minded parsers to draw inferences. In the case of hCard...
Line 158: Line 210:
   owl:sameAs <http://xmlns.com/foaf/0.1/phone>;
   owl:sameAs <http://xmlns.com/foaf/0.1/phone>;
     <http://schema.org/telephone> .
     <http://schema.org/telephone> .
</source>
== Advanced: parsing microformats in context ==
=== Representative hCard parsing ===
:''See also:'' [[representative-hcard-parsing#representative_hCard_algorithm|representative hCard algorithm]], which operates on an already parsed data model, and thus works the same way.
If the parser is able to infer that a representative hCard is present on the page, one can represent this by using <var>foaf:primaryTopic</var> from the [http://xmlns.com/foaf/spec/#term_primaryTopic FOAF specification].
<source lang="text">
<> foaf:primaryTopic _:a .
_:a a uf:h-card;
  uf:p-name "Tom Morris" .
</source>
</source>

Latest revision as of 16:29, 27 February 2017

Below is a proposed mapping of the microformats2 data model to RDF.

RDF model

In the document below, the RDF model is represented using the Notation3 syntax.

All RDF examples presume at least these basic external prefixes:

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .

In addition, we shall use the profile defined on microformats-2 as an RDF URI prefix:

@prefix uf: <http://microformats.org/profile/> .

What is the subject?

In RDF, all data is in the form of subject, predicate, object triples. These map roughly to English statements. Subjects can be either URI references or blank nodes.

Mapping these adequately is problematic.

If the element which has the root class name for a microformats2 object also has an about attribute, that SHOULD be used to set the subject for the microformat.

If the element does not have an about attribute, or the HTML processor does not support parsing about attributes, then the subject for the microformat should be an RDF blank node.

If a parser is also parsing RDFa, it should use the same blank nodes as the subjects for microformats2 objects as it does for statements expressed in RDFa. Given this HTML:

<div class="h-card p-name" typeof="foaf:Person" property="foaf:name">Tom Morris</div>

A microformats2 and RDFa-aware processor should produce Notation3 output with a singular blank node:

_:a a uf:h-card, foaf:Person;
  foaf:name "Tom Morris";
  uf:p-name "Tom Morris";
  rdfs:label "Tom Morris" .

It should not separate out these two resources into separate blank nodes:

_:a a uf:h-card;
  uf:p-name "Tom Morris";
  rdfs:label "Tom Morris" .

_:b a foaf:Person;
  foaf:name "Tom Morris" .

Representing root class names

Root class names map neatly to rdf:type. In Notation3, this is represented with the shorthand a.

<div class="h-card">Tom Morris</div>
_:bnode01 a uf:h-card .

This is compatible with the RDF specification, but differs from RDF best practice. As with Java and most programming languages, in RDF, it is customary to capitalize class names.

Representing properties

Once we have inferred the class name, we need simply declare the properties.

For each p- prefixed property, an RDF statement should be produced with the subject being that of the microformats2 object, the property being the namespaced microformats property, and the object being either a plain literal or a language literal containing the string representation of the object (see language section below). This should be equal to the string value in the JSON output.

Multiple properties

If there are multiple instances of a property, this should result in multiple statements using the same property name.

This example hCard contains two category properties and two URL properties:

<div class="h-card">
  <img class="u-photo" alt="photo of Mitchell"
       src="https://webfwd.org/content/about-experts/300.mitchellbaker/mentor_mbaker.jpg"/>
  <a class="p-name u-url"
     href="http://blog.lizardwrangler.com/" 
    >Mitchell Baker</a>
 (<a class="u-url" 
     href="https://twitter.com/MitchellBaker"
    >@MitchellBaker</a>)
  <span class="p-org">Mozilla Foundation</span>
  <p class="p-note">
    Mitchell is responsible for setting the direction and scope of the Mozilla Foundation and its activities.
  </p>
  <span class="p-category">Strategy</span>
  <span class="p-category">Leadership</span>
</div>
_:lizardwrangler a uf:h-card;
  uf:u-photo <https://webfwd.org/content/about-experts/300.mitchellbaker/mentor_mbaker.jpg>;
  uf:p-name "Mitchell Baker";
  rdfs:label "Mitchell Baker";
  uf:u-url <http://blog.lizardwrangler.com>;
  uf:u-url <https://twitter.com/MitchellBaker>;
  uf:p-org "Mozilla Foundation";
  uf:p-note "Mitchell is responsible for setting the direction and scope of the Mozilla Foundation and its activities.";
  uf:p-category "Strategy";
  uf:p-category "Leadership" .

(In Notation3, it is possible to use commas as a shorthand form to represent multiple statements. This has been avoided in order to better illustrate the point in question.)

To convert from RDF to JSON, one should take all statements that have the same subject and property and group them together into an array.

Language

RDF allows three types of literal: plain literals, language literals and typed literals.

Typed literals contain a datatype annotation, language literals contain a language annotation (the same ISO country codes as is used in HTML's lang attribute and XML's xml:lang attribute).

Processors should work out the language tag (if any) of the elements containing microformat properties (using the latest RDFa specification) and emit language-tagged literals for p- prefixed properties. If no language tag is set in the HTML, emit plain literals for all p- prefixed properties.

For instance:

<div class="h-card p-name" lang="ja">内閣総理大臣</div>

<div class="h-card p-name" lang="he">בִּנְיָמִין נְתַנְיָהוּ</div>
_:a a uf:h-card;
  uf:p-name "内閣総理大臣"@ja .

_:b a uf:h-card;
  uf:p-name "בִּנְיָמִין נְתַנְיָהוּ"@he .

rdfs:label

It is generally good practice for each resource to have an rdfs:label property. This maps to p-name.

Using Notation3 rules syntax:

@prefix log: <http://www.w3.org/2000/10/swap/log#> .
@forall ?s ?o .
{ :s uf:p-name :o . } log:implies { :s rdfs:label :o . } .

It is arguable that one may wish to then omit the p-name property from RDF representations of Microformats2 objects. The minor cost of extra duplication is outweighed by ensuring faithful representation and the ability to bidirectionally convert from RDF representations and JSON representations of Microformats2 objects.

Representing nested microformats

This is easy. Each new object becomes a new RDF resource, and there is a relationship going from the parent object to the child object.

<div class="h-event">
  <a class="p-name u-url" href="http://indiewebcamp.com/2012">
    IndieWebCamp 2012
  </a>
  from <time class="dt-start">2012-06-30</time> 
  to <time class="dt-end">2012-07-01</time> at 
  <span class="p-location h-card">
    <a class="p-name p-org u-url" href="http://geoloqi.com/">
      Geoloqi
    </a>, 
    <span class="p-street-address">920 SW 3rd Ave. Suite 400</span>, 
    <span class="p-locality">Portland</span>, 
    <abbr class="p-region" title="Oregon">OR</abbr>
  </span>
</div>

In Notation3, this would emit:

_:hevent1 a uf:h-event;
  rdfs:label "IndieWebCamp 2012";
  uf:p-name "IndieWebCamp 2012";
  uf:u-url <http://indiewebcamp.com/2012>;
  uf:dt-start "2012-06-30"^^xsd:date;
  uf:dt-end "2012-07-01"^^xsd:date;
  uf:location [
    a uf:h-card;
    rdfs:label "Geoloqi";
    uf:p-name "Geoloqi";
    uf:p-org "Geoloqi";
    uf:u-url <http://geoloqi.com/>;
    uf:p-street-address "920 SW 3rd Ave. Suite 400";
    uf:p-locality "Portland";
    uf:p-region "Oregon" .
  ].

Mapping

See also: microformats2-rdf-mapping

The RDF semantics of an hCard can be declared as an RDF document available from microformats.org. This can be used by RDF-minded parsers to draw inferences. In the case of hCard...

uf:h-card a owl:Class;
  owl:sameAs <http://www.w3.org/2006/vcard/ns#VCard> .

Equivalent properties can also be declared:

uf:p-phone a owl:DatatypeProperty;
  owl:sameAs <http://xmlns.com/foaf/0.1/phone>;
    <http://schema.org/telephone> .

Advanced: parsing microformats in context

Representative hCard parsing

See also: representative hCard algorithm, which operates on an already parsed data model, and thus works the same way.

If the parser is able to infer that a representative hCard is present on the page, one can represent this by using foaf:primaryTopic from the FOAF specification.

<> foaf:primaryTopic _:a .

_:a a uf:h-card;
  uf:p-name "Tom Morris" .