mhausenblas / lod-ng-tutorial (http://ld2sd.deri.org/lod-ng-tutorial/)
To provide a step-by-step tutorial for linked data publishing and consumption based on RDFa. We will address the following topics: (i) stepwise enrichment of a vanilla HTML page with RDFa to create a linked dataset, (ii) consumption via SPARQL, FYN, voiD, and (iii) linked data applications - from licensing to caching.
Clone this repository (size: 1.5 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/mhausenblas/lod-ng-tutorial/
| commit 13: | 1492025f263a |
| parent 12: | 0f8458748192 |
| branch: | default |
completed section comprod; added example SPARQL query. init section morecompany.
Changed (Δ3.8 KB):
raw changeset »
main.html (103 lines added, 36 lines removed)
34 |
34 |
table.example caption span { font-weight: bold;} |
35 |
35 |
table.xtab { width: 100%; padding: 2px; background: #d0d0d0;} |
36 |
36 |
table.xtab th { border: 0px; border-bottom: 1px solid #fefefe; text-align: left; padding: 2px; padding-bottom: 1px;} |
37 |
table.queryresult { border: 1px solid black; width: 100%; padding: 5px; border-collapse: collapse;} |
|
38 |
table.queryresult th { border-bottom: 1px solid black; border-right: 1px solid black; padding: 5px;} |
|
39 |
table.queryresult td { border-right: 1px solid black; padding: 5px;} |
|
37 |
40 |
</style> |
38 |
41 |
<link rel="stylesheet" type="text/css" href="W3C-ED.css" /> |
39 |
42 |
<!--<link rel="stylesheet" type="text/css" href="http://www.w3.org/StyleSheets/TR/W3C-ED" /> --> |
| … | … | @@ -91,6 +94,7 @@ href="http://lists.w3.org/Archives/Publi |
91 |
94 |
<li><a href="#baseline">2. Company Information</a></li> |
92 |
95 |
<li><a href="#products">3. Product Information</a></li> |
93 |
96 |
<li><a href="#comprod">4. Connecting Products with the Company</a></li> |
97 |
<li><a href="#morecompany">5. More Company Information</a></li> |
|
94 |
98 |
<li><a href="#references">References</a></li> |
95 |
99 |
<li><a href="#acknowledgments">Acknowledgments</a></li> |
96 |
100 |
</ul> |
| … | … | @@ -174,9 +178,9 @@ Further note that the example used throu |
174 |
178 |
We first mint a URI space for the <em>ACME Corp.</em> itself and for their products. Further, we are using the GoodRelations vocabulary (see [GR Primer] for details how to use it) to represent products and company-related information. |
175 |
179 |
</p> |
176 |
180 |
<dl class="decl"> |
177 |
<dt><tt>http://www.example.com/acme# |
|
181 |
<dt><tt>http://www.example.com/acme# ... acme:</tt></dt> |
|
178 |
182 |
<dd>the company information space (contact details, industry, products, etc.)</dd> |
179 |
<dt><tt>http://purl.org/goodrelations/v1# |
|
183 |
<dt><tt>http://purl.org/goodrelations/v1# ... gr:</tt></dt> |
|
180 |
184 |
<dd>vocabulary for representing information about companies and their products</dd> |
181 |
185 |
</dl> |
182 |
186 |
<p> |
| … | … | @@ -245,9 +249,9 @@ The resulting RDF triples (throughout sh |
245 |
249 |
<pre class="turtlecode"> |
246 |
250 |
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . |
247 |
251 |
@prefix gr: <http://purl.org/goodrelations/v1#> . |
248 |
@prefix |
|
252 |
@prefix acme: <http://www.example.com/acme#> . |
|
249 |
253 |
|
250 |
|
|
254 |
acme:corporation a gr:BusinessEntity ; |
|
251 |
255 |
rdfs:seeAlso <http://www.example.com/acme/> ; |
252 |
256 |
gr:legalName "ACME Corp." . |
253 |
257 |
</pre> |
| … | … | @@ -265,7 +269,7 @@ This resulting RDF graph from the RDFa s |
265 |
269 |
In the second step we want to add some details about the <em>products</em> itself. We are using again the GoodRelations vocabulary and a self-defined domain vocabulary for <em>tools</em>: |
266 |
270 |
</p> |
267 |
271 |
<dl class="decl"> |
268 |
<dt><tt>http://www.example.com/tools# |
|
272 |
<dt><tt>http://www.example.com/tools# ... tools:</tt></dt> |
|
269 |
273 |
<dd>the tools domain vocabulary (such as <em>hammer</em>, etc.)</dd> |
270 |
274 |
</dl> |
271 |
275 |
<p> |
| … | … | @@ -342,20 +346,20 @@ The resulting RDF triples from the RDFa |
342 |
346 |
@prefix dcterms: <http://purl.org/dc/terms/> . |
343 |
347 |
@prefix gr: <http://purl.org/goodrelations/v1#> . |
344 |
348 |
@prefix tools: <http://www.example.com/tools#> . |
345 |
@prefix |
|
349 |
@prefix acme: <http://www.example.com/acme#> . |
|
346 |
350 |
|
347 |
:corporation a gr:BusinessEntity ; |
|
348 |
rdfs:seeAlso <http://www.example.com/acme/> ; |
|
349 |
|
|
351 |
acme:corporation a gr:BusinessEntity ; |
|
352 |
rdfs:seeAlso <http://www.example.com/acme/> ; |
|
353 |
gr:legalName "ACME Corp." . |
|
350 |
354 |
|
351 |
:sf0815 a tools:AllPurposeUtility, gr:ActualProductOrServiceInstance ; |
|
352 |
dcterms:title "Stanley Fubar" . |
|
355 |
acme:sf0815 a tools:AllPurposeUtility, gr:ActualProductOrServiceInstance ; |
|
356 |
dcterms:title "Stanley Fubar" . |
|
353 |
357 |
|
354 |
:sh4711 a tools:Hammer, gr:ActualProductOrServiceInstance ; |
|
355 |
dcterms:title "Binford 2000 hammer" . |
|
358 |
acme:sh4711 a tools:Hammer, gr:ActualProductOrServiceInstance ; |
|
359 |
dcterms:title "Binford 2000 hammer" . |
|
356 |
360 |
|
357 |
:ts0007 a tools:ScrewDriver, gr:ActualProductOrServiceInstance ; |
|
358 |
dcterms:title "The Screwer" . |
|
361 |
acme:ts0007 a tools:ScrewDriver, gr:ActualProductOrServiceInstance ; |
|
362 |
dcterms:title "The Screwer" . |
|
359 |
363 |
</pre> |
360 |
364 |
<p> |
361 |
365 |
We again give a visual account of the resulting RDF graph from the RDFa snippet in Table 3. (see Fig. 2, below). |
| … | … | @@ -368,12 +372,14 @@ We again give a visual account of the re |
368 |
372 |
Note that the RDF graph in Fig. 2, above, actually consists of two unconnected sub-graphs. The upper half representing the basic <em>company</em> information, the lower half the three <em>product</em> information. This setup factually cries out for being changed, so that the <em>products</em> are connected to the <em>company</em> that is <em>offering</em> them. We will do so in the next step. |
369 |
373 |
</p> |
370 |
374 |
|
371 |
||
372 |
375 |
<!-- CONNECT PRODUCTS TO COMPANY --> |
373 |
376 |
<h2 id="comprod">4. Connecting Products with the Company</h2> |
374 |
377 |
<p> |
375 |
378 |
As stated above, we are now going to connect the <em>products</em> to the <em>company</em> that is <em>offering</em> them. In order to keep the example simple and legible we will only show the modelling and mark-up for one offering. The full example source code can be found in the accompanying document <a href="acme.html">acme.html</a>. |
376 |
379 |
</p> |
380 |
<p> |
|
381 |
In line 6 of the RDFa snippet in Table 4 we state that <em>ACME Corp.</em> has something to offer, the <code>acme:sf0815-offering</code>, which is defined in detail in the lines 28-32. The offering consists of two major components: the price specification (<code>acme:sf0815-price</code>) and a type/quantity node (<code>acme:sf0815-taqn</code>). The price specification is built around the existing cell content in lines 16-19 and the type/quantity node is represented in a hidden area (lines 23-27). |
|
382 |
</p> |
|
377 |
383 |
<table class="example"> |
378 |
384 |
<caption><span>Table 4.:</span> Connecting <em>products</em> to the <em>company</em> via <em>offerings</em>.</caption> |
379 |
385 |
<tbody> |
| … | … | @@ -457,38 +463,99 @@ The resulting RDF triples from the RDFa |
457 |
463 |
@prefix dcterms: <http://purl.org/dc/terms/> . |
458 |
464 |
@prefix gr: <http://purl.org/goodrelations/v1#> . |
459 |
465 |
@prefix tools: <http://www.example.com/tools#> . |
460 |
@prefix |
|
466 |
@prefix acme: <http://www.example.com/acme#> . |
|
461 |
467 |
|
462 |
:corporation a gr:BusinessEntity ; |
|
463 |
rdfs:seeAlso <http://www.example.com/acme/> ; |
|
464 |
gr:legalName "ACME Corp." ; |
|
465 |
gr:offers :sf0815-offering . |
|
468 |
<strong>acme:corporation</strong> a gr:BusinessEntity ; |
|
469 |
rdfs:seeAlso <http://www.example.com/acme/> ; |
|
470 |
gr:legalName "ACME Corp." ; |
|
471 |
<strong>gr:offers acme:sf0815-offering</strong> . |
|
466 |
472 |
|
467 |
:sf0815 a tools:AllPurposeUtility, gr:ActualProductOrServiceInstance ; |
|
468 |
dcterms:title "Stanley Fubar" . |
|
473 |
<strong>acme:sf0815-offering</strong> a gr:Offering ; |
|
474 |
gr:hasBusinessFunction gr:Sell ; |
|
475 |
gr:hasPriceSpecification acme:sf0815-price ; |
|
476 |
<strong>gr:includesObject acme:sf0815-taqn</strong> . |
|
469 |
477 |
|
470 |
:sf0815-offering a gr:Offering ; |
|
471 |
gr:hasBusinessFunction gr:Sell ; |
|
472 |
gr:hasPriceSpecification :sf0815-price ; |
|
473 |
gr:includesObject :sf0815-taqn . |
|
478 |
acme:sf0815-price a gr:UnitPriceSpecification ; |
|
479 |
gr:hasCurrency "EUR"^^xsd:string ; |
|
480 |
gr:hasCurrencyValue "40"^^xsd:float ; |
|
481 |
gr:hasUnitOfMeasurement "C62" . |
|
474 |
482 |
|
475 |
:sf0815-price a gr:UnitPriceSpecification ; |
|
476 |
gr:hasCurrency "EUR"^^xsd:string ; |
|
477 |
gr:hasCurrencyValue "40"^^xsd:float ; |
|
478 |
gr:hasUnitOfMeasurement "C62" . |
|
483 |
<strong>acme:sf0815-taqn</strong> a gr:TypeAndQuantityNode ; |
|
484 |
gr:amountOfThisGood "1.0"^^xsd:float ; |
|
485 |
gr:hasUnitOfMeasurement "C62" ; |
|
486 |
<strong>gr:typeOfGood acme:sf0815</strong> . |
|
479 |
487 |
|
480 |
:sf0815-taqn a gr:TypeAndQuantityNode ; |
|
481 |
gr:amountOfThisGood "1.0"^^xsd:float ; |
|
482 |
gr:hasUnitOfMeasurement "C62" ; |
|
483 |
gr:typeOfGood :sf0815 . |
|
488 |
<strong>acme:sf0815</strong> a tools:AllPurposeUtility, gr:ActualProductOrServiceInstance ; |
|
489 |
dcterms:title "Stanley Fubar" . |
|
484 |
490 |
</pre> |
485 |
491 |
<p> |
486 |
A visual representation of the resulting RDF graph from the RDFa snippet in Table 4. is shown in Fig. 3, below. |
|
492 |
A visual representation of the resulting RDF graph from the RDFa snippet in Table 4. is shown in Fig. 3, below. We note that the key path for the connection between the <em>company</em> and the <em>product</em>, that is <code>acme:corporation - gr:offers -> acme:sf0815-offering</code>, |
|
493 |
<code>acme:sf0815-offering - gr:includesObject -> acme:sf0815-taqn</code>, and finally <code>acme:sf0815-taqn - gr:typeOfGood -> acme:sf0815</code> |
|
494 |
is highlighted for better understanding. |
|
487 |
495 |
</p> |
488 |
496 |
<div class="fig"> |
489 |
497 |
<img src="img/comprod.png" width="600px" alt="Connecting products to the company via offerings in RDF" /> |
490 |
498 |
<div><span>Fig. 3.:</span> Connecting <em>products</em> to the <em>company</em> via <em>offerings</em> in RDF.</div> |
491 |
499 |
</div> |
500 |
<p> |
|
501 |
With the data we have so far, we are now able to perform a query such as shown below, allowing to retrieve pricing information about a certain tool along with the providing party (a company): |
|
502 |
</p> |
|
503 |
<pre class="turtlecode"> |
|
504 |
PREFIX gr: <http://purl.org/goodrelations/v1#> |
|
505 |
PREFIX tools: <http://www.example.com/tools#> |
|
506 |
PREFIX dcterms: <http://purl.org/dc/terms/> |
|
507 |
||
508 |
SELECT ?label ?curval ?cur ?provname |
|
509 |
WHERE { |
|
510 |
?offering a gr:Offering ; |
|
511 |
gr:includesObject ?object ; |
|
512 |
gr:hasPriceSpecification ?pricespec . |
|
513 |
?object gr:typeOfGood ?item . |
|
514 |
?item a tools:Hammer ; |
|
515 |
dcterms:title ?label . |
|
516 |
?pricespec gr:hasCurrency ?cur ; |
|
517 |
gr:hasCurrencyValue ?curval . |
|
518 |
?provider gr:offers ?offering ; |
|
519 |
gr:legalName ?provname . |
|
520 |
} |
|
521 |
</pre> |
|
522 |
<p> |
|
523 |
When the above shown query is <a href="http://tr.im/iBRX">executed</a> in a SPARQL engine such as <a href="http://sparql.org/sparql">http://sparql.org/sparql</a> with <a href="acme.html">acme.html</a> as the input RDF document, the result is as follows (we note that, as most SPARQL engines nowadays do not support RDFa directly, one has to convert the input document first to RDF/XML, for example using the <a href="http://www.w3.org/2007/08/pyRdfa/">RDFa Distiller</a>): |
|
524 |
</p> |
|
525 |
||
526 |
<table class="queryresult"> |
|
527 |
<tr> |
|
528 |
<th>label</th><th>curval</th><th>cur</th><th>provname</th> |
|
529 |
</tr> |
|
530 |
<tr> |
|
531 |
<td> "Binford 2000 hammer" </td><td> "20"^^<http://www.w3.org/2001/XMLSchema#float> </td><td> "EUR"^^<http://www.w3.org/2001/XMLSchema#string> </td><td>"ACME Corp." </td> |
|
532 |
</tr> |
|
533 |
</table> |
|
534 |
||
535 |
||
536 |
<!-- MORE COMPANY DETAILS --> |
|
537 |
<h2 id="morecompany">5. More Company Information</h2> |
|
538 |
<p> |
|
539 |
Let us now step back a bit and return to something simple though very useful in everyday commercial but also private life. We assume wants to express some more detailed information about how to contact a company or who are the people behind it. As usual we suggest to consult the stand-alone example <a href="acme.html">acme.html</a> to see the entire code in action. |
|
540 |
</p> |
|
541 |
<table class="example"> |
|
542 |
<caption><span>Table 5.:</span> Some <em>company</em> contact details.</caption> |
|
543 |
<tbody> |
|
544 |
<tr><th>Human</th><th>Machine</th></tr> |
|
545 |
<tr> |
|
546 |
<td> |
|
547 |
||
548 |
</td> |
|
549 |
<td> |
|
550 |
<pre class="rdfacode"> |
|
551 |
||
552 |
</pre> |
|
553 |
</td> |
|
554 |
</tr> |
|
555 |
</tbody> |
|
556 |
</table> |
|
557 |
||
558 |
||
492 |
559 |
|
493 |
560 |
<h2 id="references">References</h2> |
494 |
561 |
<dl> |
