Creazione e uso del dump

Un altro modo molto utile di utilizzare il mapping di D2R è quello di generare un DUMP RDF dell’ontologia.

dump-rdf

Possibili impieghi del file di dump possono essere:

  • Apertura e modifica con un tool di sviluppo per ontologie (es. TopBraid o Protégé)
  • Applicazione ad uno strumento di navigazione facet browsing come SWED (per dettagli su SWED si veda qua)
  • Importazione dentro a Semantic Media Wiki tramite SEMI (per approfondimenti si veda documentazione sul wiki Imola)
  • Generazione diagrammi e grafici con TB o Protege o altri tool
  • Importazione del dump in un triple-store tipo OpenAnzo o JENA-SDB (per la documentazione su SDB si veda qua)
  • Connessione ad un altro endpoint SPARQL (soluzione al problema delle federated query) tipo JENA-JOSEKI (vedi documentazione su wiki)
  • ...e poi spazio alla fantasia!

Per generare il dump con D2R a partire da un file di mapping è possibile utilizzare il comando\ dump-rdf.bat (o dump-rdf per Linux) da prompt (nella root di d2r-server):

\> dump-rdf.bat -m custommapping\D2RUnionMappingProgeReq.n3 -f N3 -b http://www.imolinfo.it/ontologie/esempiocorso/istanze# -o dump_esempio.n3

Con questo commando si specifica nell’ordine:

  • -m - percorso relativo o assoluto del file di mapping
  • -f - formato del file di mapping (default "RDF/XML", "RDF/XML-ABBREV", "N3", "N-TRIPLE")
  • -b - il namespace da associare all’ontologia generata
  • -o - il nome del file di output

Per una lista completa sui parametri da passare a dump-rdf si veda la documentazione ufficiale qua.

Una volta terminato il dump (su DB molto grandi e mapping complessi può impiegare anche qualche minuto), avremo un file con tutte le istanze (e anche parte del modello se non specificato diversamente con serveVocabulary) valorizzate e pronte per essere utilizzate come da elenco sopra.

Di seguito riportiamo un estratto del file N3 generato nell’esempio in (dump_esempio.n3):

@prefix : \<http://www.imolinfo.it/ontologie/esempio_corso/istanze#\> .

@prefix foaf: \<http://xmlns.com/foaf/0.1/\> .

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

@prefix spec-m: \<http://www.imolinfo.it/ontologie/esempio_corso/specifiche#\> .

@prefix d2r:\<http://sites.wiwiss.fu-berlin.de/suhl/bizer/d2r-server/config.rdf#\> .

@prefix xsd: \<http://www.w3.org/2001/XMLSchema#\> .

@prefix owl: \<http://www.w3.org/2002/07/owl#\> .

@prefix map: \<file:/SIAFMappingGBS_v2.n3#\> .

@prefix rdf: \<http://www.w3.org/1999/02/22-rdf-syntax-ns#\> .

@prefix vocab: \<http://localhost:2020/vocab/resource/\> .

@prefix doap: \<http://usefulinc.com/ns/doap#\> .

@prefix skos: \<http://www.w3.org/2004/02/skos/core#\> .

:person-2

a foaf:Person ;

rdfs:label "Claudio Bianchi"^^xsd:string ;

foaf:currentProject :progetto-3 ;

foaf:family_name "Bianchi"^^xsd:string ;

foaf:firstName "Claudio"^^xsd:string ;

foaf:mbox "claudio.bianchi@esempio-corso.it"^^xsd:string .

spec-m:data_inizio

a rdf:Property .

spec-m:ProgettoSoftware

a rdfs:Class .

:progetto-2

a spec-m:ProgettoSoftware ;

rdfs:label "Libro unico del lavoro"^^xsd:string ;

doap:maintainer :person-1 ;

spec-m:data_fine "2011-03-31T00:00:00"^^xsd:dateTime ;

spec-m:data_inizio "2011-01-01T00:00:00"^^xsd:dateTime .

.

.

.

:testcase-2-fun_1-1

a spec-m:TestCase ;

rdfs:label "Accesso alla sezione di documenti LUL"^^xsd:string ;

spec-m:ha_input "Accesso alla sezione di documenti LUL"^^xsd:string ;

spec-m:haoutputatteso

"Visualizzazione della lista con tutti i documenti"^^xsd:string ;

spec-m:progetto_relativo

:progetto-2 ;

spec-m:testcasedi :requisito-fun_1 .

:testcase-3-fun_100-1

a spec-m:TestCase ;

rdfs:label "Inviare un … il pulsante ricevi"^^xsd:string ;

spec-m:ha_input "Inviare un messaggio alla casella, … ricevi"^^xsd:string ;

spec-m:haoutputatteso

"Il messaggio inviato appare nella lista"^^xsd:string ;

spec-m:progetto_relativo

:progetto-3 ;

spec-m:testcasedi :requisito-fun_100 .

:progetto-3

a spec-m:ProgettoSoftware ;

rdfs:label "Web Mail Legalmail"^^xsd:string ;

doap:maintainer :person-2 ;

spec-m:data_fine "2011-04-14T00:00:00"^^xsd:dateTime ;

spec-m:data_inizio "2011-04-12T00:00:00"^^xsd:dateTime .

doap:maintainer

a rdf:Property .

:person-3

a foaf:Person ;

rdfs:label "Marco Nei"^^xsd:string ;

foaf:currentProject :progetto-4 ;

foaf:family_name "Nei"^^xsd:string ;

foaf:firstName "Marco"^^xsd:string ;

foaf:mbox "marco.neri@esempio-corso.it"^^xsd:string .

.

.

.

Importazione modelli

Per i tool che usano o necessitano dell’importazione dei modelli usati, come per esempio TopBraid, è possibile effettuare l ‘import da dentro l’ide specificando i file che si vogliono importare oppure si riesce a generare con D2R lo statement di import in modo che il file possa già dichiarare il

modello importato.

Di seguito si riporta un esempio per aggiungere l’import di un modello solo e la specifica del namespace relativo alle istanze:

map:Ontology a d2rq:ClassMap;

d2rq:dataStorage map:database;

d2rq:uriPattern "http://www.mps.it/ontologie/EA/v1.0/state-model-mps-istanze" ;

d2rq:class owl:Ontology;

.

map:Ontology_Import

rdf:type d2rq:PropertyBridge ;

d2rq:belongsToClassMap

map:Ontology ;

d2rq:constantValue \<http://www.mps.it/ontologie/EA/v1.0/mps-state-model\>;

d2rq:property owl:imports;

.

Dove:

  • \<http://www.mps.it/ontologie/EA/v1.0/mps-state-model\> va sostituito con il namespace del modello che si vuole importare nel file di istanze. Se il modello è più di uno (nel caso dello state model solitamente basta lui che a sua volta include il resto) si andranno a specificare più PropertyBridge ognuno col suo import (es. OntologyImport1, OntologyImport2 ecc…).

Questi namespace saranno specifici a seconda del contesto.

Uso delle API D2R con JENA

Uno degli aspetti più interessanti di D2R è costituito dalla possibilità di usarlo via programmatica direttamente integrato con il JenaModel. Ciò di fatto permette di riprodurre tutte le funzionalità del servizio e del dump da un programma Java e in particolare di poter trattare una istanza di D2R che mappa una o più sorgente dati come un normale modello di JENA.

Al momento non sono ancora stati approfonditi questi aspetti ma nel caso si rendano necessari è consigliabile fare riferimento alla guida ufficiale (corredata di ottimi esempi) e, perché no, aggiornare e integrare questo HowTo interno.

Per il momento questo è il riferimento alla guida sulle API di D2R e relativo uso con JENA:

<img src="media/image2.wmf" style="width:0.40347in;height:0.49028in" alt="C:\Users\Matteo\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.IE5\SUD3RLCV\MC900343747[1].wmf" /><http://www4.wiwiss.fu-berlin.de/bizer/d2rq/spec/#usingD2RQ>

D2R Server Update

Esiste anche una estensione prototipo di D2R Server che oltre a mappare in lettura permette di utilizzare il linguaggio di update SPARQL Update (non standard) per scrivere sulle sorgenti mappate.

Questa funzionalità aprirebbe le porte ad una visione architetturale più consistente e ampia in cui D2R recita un ruolo centrale nell’integrazione completa (bidirezionale) fra il mondo delle ontologie e quello delle sorgenti RDB.

Al momento non è ancora stato provato internamente. Non appena sarà fatto qualche test questa parte del documento verrà aggiornata. Al momento riportiamo il link di riferimento: <http://d2rqupdate.cs.technion.ac.il/>

Note e consigli

In questo paragrafo riportiamo alcuni consigli e appunti derivanti dall’esperienza sul campo. L’intento è quello di riportare casi o soluzioni a problemi che possono verificarsi facilmente quando si crea un mapping con D2R.

Creazione di Tassonomie da File Excel

Un mapping tipico che viene richiesto è quello a partire da sorgenti piuttosto piatte come i File Excel, in cui sono state riportate in qualche modo delle tassonomie, magari anche complesse.

Ora, in una ontologia ci sono due modi per rappresentare una tassonomia:

1. tramite una alberatura di classi OWL

2. tramite una alberatura di istanze

Il primo caso è utile quando si dovranno di fatto creare vere e proprie istanze di quella tassonomia con tanto di ereditarietà multipla (es. Classificazione di concetti inerenti i progetti: ProgettoXYZ is-a Progetto). In questo caso, stiamo parlando di classi di modello e quindi, solitamente, la generazione delle classi viene fatta a mano. In alternativa è possibile generarle anche con D2R definendo un ClassMap su owl:Class e dei PropertBridge per mappare le meta relazioni rdfs:isSubClassOf, rdfs:label e rdfs:comment.

NOTA – ATTENZIONE: generare una tassonomia di classi OWL in maniera automatica da una alberatura esistente può portare ad avere un modello pesante e semanticamente scorretto in quanto le classi sarebbero solo una alberatura senza una vera caratterizzazione (relazioni e proprietà) e molto spesso potrebbero non rispettare il concetto di “sotto insieme di” previsto dalla semantica di owl:Class. Per esempio, potrebbe capitare di avere un’ alberatura basata sulla relazione “fatto_di” o “contiene”. Un esempio potrebbe essere un processo fatto di sottoprocessi che lo compongono e magari ogni sotto processi fatto di attività. Questa è una tassonomia ma non intesa come la intende OWL a livello di modello (owl:Class e rdfs:isSubClassOf).

La semantica di meta-modello di OWL è quella di sotto-insieme ossia:

se B isSubClassOf A e C rdf:type B allora C è anche istanza di A

Per tanto è necessario verificare bene che tipo di soluzione adottare.

Il secondo caso invece è indicato quando ogni nodo dell’albero di classificazione non dovrà essere istanziato ma usato come possibile riferimento da altre istanze per connotare una particolare classificazione relativa ad una precisa tassonomia.

Un esempio di questo caso potrebbe essere una tassonomia di processi o di aree o una categorizzazione di componenti architetturali che possa essere puntata da istanze di componenti software per indicarne il posizionamento nella classificazione architetturale (es. L’istanza di ComponenteSoftware MySQL_5.1 è classificato architetturalmente come RDBMS o più genericamente come Storage).

Per velocizzare questo tipo di mapping e quindi creare una struttura tassonomica basata su una classe di tipo nodo e delle istanze legate fra loro da una relazione gerarchica da padre a figlio, a partire da una rappresentazione excel, molto spesso è necessario adattare il file excel stesso per rendere più semplice e ripetibile il mapping con D2R.

A questo scopo è stato creato un pacchetto contenente il file excel e il file di mapping da scaricare e usare per capire meglio questo sistema (su SVN).

Il template di excel rappresenta una tassonomia astratta a tre livelli con una sola radice:

<img src="media/image3.png" style="width:6.22639in;height:2.15069in" />

Nel template, ogni colonna rappresenta un livello della tassonomia. La struttura dell’excel è predefinita e deve rispettare la seguente regola:

1. Ogni nodo di livello M ha almeno una cella \<rigaN,colonnaM\> per cui la cella successiva \<rigaN,colonnaM+1\> è vuota. Questa riga servirà al mapping per istanziare quel nodo al livello M della tassonomia e specificare suo padre come valore della cella \<rigaN,colonnaM-1\> con l’eccezione della prima colonna (nodo radice) che non avrà padre.

Nell’esempio dell’immagine, la cella \<3,B\> ha la cella \<3,C\> vuota e quindi può essere riconosciuta dal classMap condizionale per i nodi di livello 2 (3-1 perché la prima riga viene considerata di header anche dal mapping). Stessa cosa dicasi per la cella \<2,A\> che mappa il nodo root di livello 1 e la cella \<4,C\> che mappa il nodo di livello 3.

Nel file di mapping verrà quindi definito un ClassMap condizionale per ogni livello in cui la condizione della regola appena citata è relativa al suo livello e a cui sarà attaccato un PropertyBridge relativo per la creazione del padre.

Di seguito si riporta l’esempio per la creazione delle istanze di Taxonomic-Node a livello 2 con padre di livello 1:

map:Secondo_Livello a d2rq:ClassMap;

d2rq:dataStorage map:database;

d2rq:condition "Tassonomia\$.secondo_livello \<\> ''" ;

d2rq:condition "Tassonomia\$.terzo_livello IS NULL" ;

d2rq:uriPattern "@@Tassonomia\$.secondo_livello\|urlify@@";

d2rq:class :Taxonomic-Node;

.

map:SecondoLivelloLabel

rdf:type d2rq:PropertyBridge ;

d2rq:belongsToClassMap map:Secondo_Livello;

d2rq:property rdfs:label ;

d2rq:datatype xsd:string ;

d2rq:column "Tassonomia\$.secondo_livello" ;

.

map:SecondoLivelloisSubNodeOf a d2rq:PropertyBridge;

d2rq:belongsToClassMap map:Secondo_Livello;

d2rq:property :isSubNodeOf;

d2rq:uriPattern "@@Tassonomia\$.primo_livello\|urlify@@";

.

Si nota che oltre all’istanza e al collegamento col padre (isSubNodeOf) viene anche mappata la label.

NOTA – LA CLASSE DI NODO: è necessario definire una classe Taxonomic-Node per poter associare ad essa la proprietà riflessiva isSubNodeOf e da essa istanziare tutti i nodi di tutti i livelli connessi tramite questa proprietà. Ovviamente è possibile decidere di usare una classe diversa esistente (esempio SKOS concept) o una definita diversamente.

Sempre nella cartella su SVN <https://version.imolinfo.it/svn/SemanticWeb/D2RMappingDiTassonomiaDaExcel_templates> è stato versionato il dump N3 associato all’esempio del template.

Di seguito si mostra il risultato del dump-rdf caricato in TopBraid (si vedono solo due livelli perché il terzo è stato mappato come foglia e quindi è relazionato ai nodi di secondo con una relazione diversa (isLeafOf anziché isSubNodeOf):

<img src="media/image4.png" style="width:4.41528in;height:1.33958in" />

NOTA – CONSIDERAZIONE: questo approccio è lo stesso usato per creare le tassonomie ABILab reperibili qua: <https://version.imolinfo.it/svn/Ontologie/trunk/ABI%20Lab>

NOTA – BEST PRACTICE DI MODELLAZIONE: il motivo per cui si preferisce sempre usare una relazione da figlio a padre (es. rdfs:isSubClassOf o isSubNodeOf o isLeafOf) per generare tassonomie è che risulta, dal punto di vista computazionale, più semplice gestire delle relazioni da una a pochi (padri) che da uni a molti (figli). E’ quindi best practice di modellazione usare sempre relazioni tassonomiche che vanno verso la radice e non verso le foglie.

E’ consigliato quindi usare questo approccio, copiandosi e customizzando le risorse versionate su SVN, per adattare in primis il file di Excel da cui si deve partire, in modo che rispetti la regola 1 poi per definire il file di mapping relativo (magari adattando quello del template).

Problemi negli uriPattern con “-“

Si è notato che D2R non riesce ad effettuare correttamente le query quando nell’uriPattern ci sono caratteri come “-”.

Per esempio, se un uri Pattern è del tipo:

d2rq:uriPattern "@@Temp-late\$.secondo_livello@@";

cioè, il nome della colonna che si sta mappando contiene il carattere “-”, il dump darà un messagio di errore di questo tipo:

<img src="media/image5.png" style="width:5.78333in;height:0.20764in" />

Per risolvere questo problema si consiglia di non usare il carattere in questione.

Riferimenti

  • \
  • [1\] Un tutorial abbastanza completo sull’uso di D2R Server con un DB MySQL

<http://sw.cs.technion.ac.il/d2rq/tutorial>

  • \
  • [2\] Guida per connettere una sorgente relazionale mappata tramite D2R con l’endpoint JOSEKI 2

<http://www4.wiwiss.fu-berlin.de/bizer/d2rmap/usecases/joseki/D2R4joseki2.pdf>

  • \
  • [3\] D2R/Update Server, un tutorial sull’uso di D2R Server per effettuare query con SPARQL Update e quindi andare in scrittura sul DB

<http://d2rqupdate.cs.technion.ac.il/tutorial>

  • \
  • [4 \] SPARQL 1.1 Update. W3C Working Draft

<http://www.w3.org/TR/2009/WD-sparql11-update-20091022/>