Affrontiamo in questo articolo il concetto di “vocabolario controllato”, ossia un set di termini non ambigui e non ridondanti sotto il controllo di un‘authority che ne garantisce l‘integrità e la gestione.
Introduzione
Nello scorso numero [MOKA_SEMW_1] abbiamo introdotto i principi base e il data model di RDF. Abbiamo inoltre fatto pratica con le API Jena e con Joseki.
Figura 1 – Sematic Web Stack: RDF & RDFS
In questo articolo approfondiremo RDFS e parleremo di vocabolari controllati.
Vocabolari controllati
Che cosa è un vocabolario? Un vocabolario è un elenco di parole alle quali vengono associati uno o più significati. Esempi di vocabolari sono VCARD [WP_VCARD], Dublin Core [WP_DC], FOAF (friend-of-a-friend) [WP_FOAF] e DOAP (Description Of A Project) [WP_DOAP].
Il Semantic Web estende questa nozione, con il concetto di “vocabolario controllato”, ossia un set di termini non ambigui e non ridondanti sotto il controllo di un’authority che ne garantisce l’integrità e la gestione (ad esempio lo standard vCard è gestito dall’Internet Mail Consortium [IMC] mentre il Dublin Core Metadata Iniziative [DCMI] è l’organizzazione responsabile della manutenzione del Dublin Core). Ogni termine di un vocabolario RDF è associato ad un URI, che ne identifica univocamente il significato (questo risolve il problema delle parole omografe).
VCARD
VCARD (o “scheda di indirizzi virtuale”) è un formato che permette lo scambio di dati personali (PDI: Personal Data Interchange) tra le applicazioni.
Gli esempi proposti lo scorso numero usavano il dizionario VCARD (definito all’URL: http://www.w3.org/2001/vcard-rdf/3.0#) e il programma Java usava le costanti definite nella classe com.hp.hpl.jena.vocabulary.VCARD.
// create an empty model Model model = ModelFactory.createDefaultModel(); // Creo la Risorsa srossini in un unico passo in ("cascading style") Resource ste = model.createResource("https://www.mokabyte.it/StefanoRossini") .addProperty(VCARD.EMAIL, "srossini@mokabyte.it"); model.write(new FileOutputStream(FILE_NAME_NTRIPLE), "N-TRIPLE");
Sempre negli esempi dello scorso articolo sono state utilizzate le costanti VCARD.FN per definire il Full Name (nome completo), VCARD.NCIKNAME per il soprannome e VCARD.EMAIl per l’email.
Resource stefanoRossini = model.createResource("https://www.mokabyte.it/StefanoRossini") .addProperty(VCARD.FN, "Stefano Rossini") .addProperty(VCARD.NICKNAME, "Metallian King") .addProperty(VCARD.N, model.createResource() .addProperty(VCARD.EMAIL,"srossini@mokabyte.it"));
Ottenendo la seguente serializzazione:
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns_vcard="http://www.w3.org/2001/vcard-rdf/3.0#" > srossini@mokabyte.it Metallian King Stefano Rossini
Per vedere il corrispondente grafo dello statement creato, senza “scomodare” tool RDF, è possibile collegarsi all’URL del W3C Validation service [W3CVS] http://www.w3.org/RDF/Validator/direct e inserire nell’apposita text field l’RDF in esame.
Figura 3 – W3C Validation Service
Il risultato ottenuto è riportato nella immagine di figura 4:
Figura 4 – Grafo dell’esempio vCard proposto
Ci si pone ora il problema di come creare un proprio vocabolario per un proprio dominio di business.
Come esempio ci si riferisce al dominio MokaByte. Semplificando il contesto, immaginiamo che articoli e autori vengano archiviati su database relazionale attraverso le due tabelle ARTICLES e AUTHORS affiancate da un’ulteriore tabella ARTICLES_AUTHORS (che esprime la relazione, di cardinalità N : M tra Autori e Articoli).
Figura 5 – Modello ER dell’esempio proposto
Riprendendo l’analogia tra il data model Entity-Relationship e il data model RDF introdotta in [MOKA_SEMW_1], si procede a tradurre la base dati in RDF seguendo le seguenti regole:
- una riga di una tabella corrisponde a un insieme di statement (asserzioni) RDF relative alla stessa Risorsa
- il nome di ciascun campo (cioè di ciascuna colonna) è il nome di una Proprietà RDF
- il valore del campo è il valore della Proprietà RDF (cioè è l’Object della Proprietà)
Per cui, prendendo in esame la risorsa “www.mokabyte.itStefano Rossini” come elemento dell’insieme Autori e “www.mokabyte.itSemantic Web” come elemento dell’insieme Articoli, i vari statement risulteranno essere del tipo:
- https://www.mokabyte.it/StefanoRossini hasName Stefano
- https://www.mokabyte.it/StefanoRossini hasSurname Rossini
- https://www.mokabyte.it/StefanoRossini Rossini hasEmail srossini@mokabyte.it
- https://www.mokabyte.it/SematicWeb hasTitle Semantic Web
- https://www.mokabyte.it/SematicWeb hasAuthor https://www.mokabyte.it/StefanoRossini Rossini
- . . . . .
In modo programmatico, con Jena, questo si traduce nel creare un nuovo Model al quale agganciare due nuovi oggetti di classe Resource (Articolo e Autore) e la nuova Property hasAuthor (per motivi di sintesi è l’unica proprietà presa in considerazione).
Il passo successivo prevede di mettere in relazione le due nuove risorse attraverso la nuova proprietà, ottenendo lo statement ha autore .
String autore = "https://www.mokabyte.it/StefanoRossini"; // risorsa autore String articolo = "https://www.mokabyte.it/SematicWeb"; // risorsa articolo String mokaDicUri = "https://www.mokabyte.it/2007/04/moka_dic/1.0#"; // URI vocabolario String hasAuthor = "hasAuthor"; // proprietà try { // creazione di un Model vuoto Model model = ModelFactory.createDefaultModel(); // Creo la risora articolo Resource articoloResource = model.createResource(articolo); // Creo la risora autore Resource autoreResource = model.createResource(autore); // Creo il predicato (property) => la proprietà hasAuthor Property hasAuthorProperty = model.createProperty(mokaDicUri, hasAuthor); // Aggiungo le propreità con i relativi valori articoloResource.addProperty(hasAuthorProperty, autoreResource);
La corrispondente serializzazione XML dell’esempio proposto è la seguente:
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:j.0="https://www.mokabyte.it/2007/04/moka_dic/1.0#" >
Il relativo grafo della tripla soggetto-predicato-oggetto, ottenuto mediante il W3C Validation service, è riportato nell’immagine che segue:
Figura 6 – Grafo dello statement dell’esempio proposto
Vocabulary Wrapper Class
Come si vede, nel codice appena proposto, le definizioni delle risorse e della proprietà del dizionario sono “hardcoded”, cioè inglobate direttamente nel codice del programma. Questo crea un codice scomodo da leggere e poco manutenibile.
Per migliorare il programma si può creare una classe che incapsula le costanti che definiscono le risorse RDF. Tale classe di fatto agisce da wrapper del dizionario che si sta costruendo. La classe wrapper, incapsula le definizioni e le caratteristiche del dizionario, permettendo di scrivere un codice Java più compatto e “pulito”. Tale operazione è analoga a quanto già fatto da Jena con VCARD vista negli esempi del precedente numero.
Figura 7 – La classe com.hp.hpl.jena.vocabulary.VCARD
La classe com.hp.hpl.jena.vocabulary.VCARD è la rappresentazione Java dei vocaboli del dizionario VCARD e semplifica l’utilizzo dello stesso in modo programmatico.
Figura 8 – Utilizzo della classe com.hp.hpl.jena.vocabulary.VCARD
Riprendendo l’esempio dello sviluppo di un proprio vocabolario, si implementa la classe Vocabulary Wrapper di nome MOKADIC che prevede la definizione della proprietà “ha autore” di nome hasAuthor.
La classe MOKADIC
La classe MOKADIC deve prevedere la costante URI (l’URI del dizionario) e le relative proprietà.
public class MOKADIC { // URI degli elementi del vocabolario protected static final String URI = "https://www.mokabyte.it/2007/04/moka_dic/1.0#"; // Return URI public static String getURI( ){ return URI; } // Definisco i nomi delle proprietà e le proprietà stesse private static final String hasAuthorName = "hasAuthor"; /** Proprietà haAutore: l'autore dell'articolo di Mokabyte */ public static Property hasAuthor = null; // Istanzio le proprietà e le risorse del vocabolario static { try { // Istanzio la proprietà hasAuthor hasAuthor = new PropertyImpl(URI, hasAuthorName); } catch (Exception e) { e.printStackTrace(); } } }
Creata la classe wrapper MOKADIC si procede modificando il precedente esempio.
String autore = "https://www.mokabyte.it/StefanoRossini"; // risorsa autore String articolo = "https://www.mokabyte.it/SematicWeb"; // risorsa articolo try { Model model = ModelFactory.createDefaultModel(); // Creo la risora articolo Resource articoloResource = model.createResource(articolo); // Creo la risora autore Resource autoreResource = model.createResource(autore); // Associo alla risorsa articolo la risorsa autore articoloResource.addProperty(MOKADIC.hasAuthor, autoreResource);
Come si vede il nuovo codice risulta più “pulito”, compatto e leggibile rispetto alla precedente versione. Con la classe wrapper la proprietà “ha autore” è definita dalla Property MOKADIC.hasAuhtor. Lo sviluppatore si deve concentrare solo nel definire il soggetto e l’oggetto per comporre correttamente lo statement: “articolo <> autore”.
La serializzazione che si ottiene è la medesima dell’esempio precedente.
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:j.0="https://www.mokabyte.it/2007/04/moka_dic/1.0#" >
Il namespace del vocabolario MOKADIC è stato dichiarato con prefisso “j:0”, tale prefisso viene generato automaticamente da Jena. Per specificare un proprio prefisso per il namespace è possibile utilizzare le API Jena mediante il metodo setNsPrefix(String prefix, String URI) della classe Model. Tramite questo metodo è possibile definire il prefisso da utilizzare per un determinato namespace. Ad esempio, volendo applicare il prefisso “mokadic” agli statement definiti con il vocabolario MOKADIC, è sufficiente utilizzare il metodo setNSPrefix nel seguente modo:
String ns = "mokadic"; model.setNsPrefix(ns, MOKADIC.getURI()); ... articoloResource.addProperty(MOKADIC.hasAuthor, autoreResource); ...
Il risultato che si ottiene è che nell’RDF il prefisso per gli elementi del Moka dictionary è “mokadic” e non più “j:0”.
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns_mokadic="https://www.mokabyte.it/2007/04/moka_dic/1.0#" >
Nel caso in cui si avesse la necessità di specificare più prefissi è possibile utilizzare il metodo setNsPrefix(Map arg).
Map nsMap; nsMap = new HashMap(); nsMap.put("mokadic", MOKADIC.getURI()); nsMap.put("kok", KING_OF_KINGS_CLASSIFICATION.getURI()); model.setNsPrefixes(nsMap);
Il prossimo passo che verrà affrontato, prevede di sfruttare ulteriormente le potenzialità espressive di RDF mediante la definizione del tipo di ciascuna risorsa. In RDF è possibile assegnare il tipo a una risorsa mediante la proprietà . L’attributo rdf:type di fatto specifica l’URI della risorsa corrispondente alla definizione del tipo.
Per utilizzare i tag previsti da RDF, Jena mette a disposizione la classe warpper com.hp.hpl.jena.vocabulary.RDF con le relative costanti. Per tipizzare le risorse del Moka dictionary, nella classe MOKADIC si definisce la risorsa e il suo nome:
private static final String tipoMokaArticolo = "MokabyteArticle"; public static Resource tipoMokaArticoloResource = null;
per poi istanziarla nel blocco static analogamente a quanto avviene per la proprietà hasAuthor.
tipoMokaArticoloResource = new ResourceImpl(URI+tipoMokaArticolo);
Successivamente si aggiunge il tipo appena definito nel MOKADIC alla risorsa mediante il solito metodo addProperty():
addProperty(RDF.type, MOKADIC.tipoMokaArticoloResource);
Nella nuova serializzazione ottenuta viene indicato il tipo della risorsa mediante il tag :
. . . . . .
È possibile arricchire ulteriormente gli statement RDF fino ad ora prodotti aggiungendo a corredo anche i tag previsti da RDFS, per i quali Jena mette a disposizione la classe wrapper com.hp.hpl.jena.vocabulary.RDFS con le relative costanti:
public class RDFS { protected static final String uri = "http://www.w3.org/2000/01/rdf-schema#"; public static final Resource Class = resource("Class"); public static final Resource Datatype = resource("Datatype"); . . . public static final Property comment = property("comment"); public static final Property label = property("label"); . . . public static final Resource Literal = resource("Literal"); public static final Resource Resource = resource("Resource"); }
Come esempio vengono introdotti rdfs:comment e rdfs:label che sono, rispettivamente, la proprietà per specificare la descrizione e l’etichetta della risorsa. A livello Java il codice è semplice ed immediato:
Resource articoloResource1 = model.createResource("https://www.mokabyte.it/dd_mm_yyyy/ejb3.0") . . . .addProperty(RDFS.label, "EJB 3.0") .addProperty(RDFS.comment, "Un articolo moka J2EE") . . .
La relativa serializzazione RDF è la seguente:
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns_rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns_mokadic="https://www.mokabyte.it/2007/04/moka_dic/1.0#" > . . . . EJB 3.0 Un articolo moka J2EE . . . .
Attenzione: non sempre è conveniente costruire un proprio vocabolario, soprattutto quando le stesse definizioni del vocabolario che si intende costruire sono presenti in vocabolari già esistenti e controllati. A tal proposito, si vedrà ora come sviluppare lo stesso esempio utilizzando il vocabolario controllato Dublin Core. Il vantaggio del Dublin Core è quello di essere un vocabolario standard e controllato dalla Dublin Core Metadata Initiative. In Jena esiste la classe com.hp.hpl.jena.vocabulary.DC che è la classe Vocabulary wrapper che permette di utilizzare i vocaboli del Dublin Core.
Il Dublin Core
Il Dublin Core è un sistema di metadata costituito da un nucleo di elementi essenziali ai fini della descrizione di qualsiasi materiale digitale accessibile via rete informatica. Il progetto del Dublin Core si è sviluppato in ambito OCLC (Online Computer Library Center), la grande rete di servizi americana per le biblioteche. Nel marzo 1995 si è tenuta una conferenza nella città americana di Dublin (Ohio), nella quale i partecipanti (bibliotecari, archivisti, editori, ricercatori e sviluppatori di software, oltre ad alcuni membri dai gruppi di lavoro dell’IETF, Internet Engineering Task Force) si sono trovati d’accordo sulla necessità di creare un insieme di strumenti condivisi per l’accesso alle risorse digitali. Lo scopo era quello di stabilire un insieme base di elementi descrittivi che potessero essere forniti dall’autore o dall’editore dell’oggetto digitale, e in esso potessero essere inclusi o da esso potessero essere referenziati. Il consorzio di utenti che si è costituito ha incominciato così a sviluppare un’architettura per i metadata che venisse incontro alle necessità dei venditori e dei produttori di informazioni (vedere [WP_DC]).
Gli elementi costitutivi del nucleo (dicembre 1996) sono i seguenti:
- Titolo (Title)
- Creatore (Creator)
- Soggetto (Subject)
- Descrizione (Description)
- Editore (Publisher)
- Data (Date)
- Tipo (Type)
- Identificatore (Identifier)
- Lingua (Language)
- Relazione (Relation)
- Riferimento a una risorsa correlata
Esempio con DC
Per l’esempio si pone l’attenzione sul vocabolo “Creatore” (DC:creator). Il “creatore” è l’entità che ha la responsabilità principale della produzione del contenuto della risorsa. Esempi di Creator includono una persona, un’organizzazione o un servizio responsabili del contenuto intellettuale della risorsa. Da un punto di vista di sviluppo, questo si traduce nell’utilizzo della classe com.hp.hpl.jena.vocabulary.DC e della proprietà DC.creator. Sostituendo nell’esempio Java la proprietà MOKADIC.hasAuhtor con la nuova DC.creator, si ha
String autore = "https://www.mokabyte.it/StefanoRossini"; // risorsa autore String articolo = "https://www.mokabyte.it/SematicWeb"; // risorsa articolo // create an empty model Model model = ModelFactory.createDefaultModel(); // Create the resource and add the properties cascading style Resource articoloResource = model.createResource(articolo) .addProperty(DC.creator, model.createResource(autore));
Si ottiene pertanto la seguente serializzazione XML:
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns_dc="http://purl.org/dc/elements/1.1/" >
Il corrispettivo grafo dello statement creato, ottenuto tramite W3C Validation service, è il seguente:
Figura 9 – Grafo dello statement dell’esempio proposto
Tale grafo è “semanticamente” equivalente al precedente ottenuto con la proprietà hasAuthor del vocabolario MOKADIC.
Oltre al Dublin Core esitono altri vocabolari controllati utili come ad esempio Friend-of-a-friend (FOAF).
FOAF
FOAF è acronimo di Friend-of-a-friend, “l’amico di un mio amico”, ossia il misterioso personaggio cui capitano tutte le vicende raccontate nelle leggende metropolitane di mezzo mondo. Tale acronimo è anche il nome del progetto FOAF-project.org, un progetto di Semantic Web che mira a creare una rete di amici-degli-amici utilizzando un vocabolario RDF comune chiamato appunto FOAF [WP_FOAF].
FOAF codifica in formato standard i dati personali e le relazioni tra persone (gruppi di persone, comunità, aziende). In un file FOAF vengono inseriti la descrizione di un singolo e un elenco di contatti (friends): amici, collaboratori, colleghi, etc. L’idea di fondo è quella che, per cercare una persona, si possa fare come nella vita di tutti i giorni, muovendosi tra le proprie e altrui conoscenze. Il tutto si basa su un file di metadati RDF legato a una pagina personale, che oltre a specificare dati e caratteristiche della persona, permette di ricostruire un elenco di altre pagine e dei relativi metadati (la rete di amici).
L’inventore dell’acronimo FOAF, lo studioso di folklore americano Jan Harold Brunvald, riteneva che l’analisi della diffusione di una leggenda metropolitana permettesse di studiare come gruppi sociali o comunità differenti comunicassero tra loro: una leggenda che ha origine, per esempio tra gli studenti di liceo, può successivamente diffondersi in ambienti completamente diversi, come quello delle casalinghe. Conoscere il “percorso” che una determinata leggenda ha seguito da una comunità all’altra può aiutarci a comprendere la natura dei loro rapporti [WP_FOAF]).
Per generare automaticamente la propria descrizione in formato FOAF è sufficiente compilare i campi presenti in un apposito servizio di FOAF-a-matic [FAM], una semplice applicazione JavaScript che permette di creare una descrizione di noi stessi in formato FOAF.
Figura 10 – FOAF-a-matic
<rdf:RDF xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns_rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns_foaf="http://xmlns.com/foaf/0.1/" xmlns_admin="http://webns.net/mvcb/"> Stefano Rossini Dott Stefano Rossini Metallian King Brother Of Metal . . . Adrian
Il MOKADIC
Riprendendo il discorso su come creare un dizionario significativo che rappresenti le informazioni relative al proprio dominio di business, è necessario definire quali siano le informazioni di rilievo. Per il MOKADIC verranno prese in considerazione le seguenti proprietà:
- l’autore dell’articolo
- il nome e il cognome dell’articolista
- l’email dell’autore
- il titolo dell’articolo
- la sezione MokaByte a cui appartiene l’articolo (New trends, JumpStart, J2SE, J2EE, J2ME, Integrazione, Metodologia, Project Management)
Figura 11 – Alcune categorie degli articoli di MokaByte
Per le informazioni dell’articolista, piuttosto che definire nuove proprietà, si utilizzeranno quelle standard dei vocabolari controllati e quindi maggiormente interoperabili rispetto a eventuali vocaboli proprietari. Verranno utilizzati i vocaboli DC per descrivere i dati dell’articolo, VCARD per specificare i dati dell’autore e FOAF, in modo un pò “forzato” ma utile dal punto di vista didattico, per indicare gli articolisti MokaByte con cui l’autore collabora.
Per quanto riguarda la classificazione degli articoli secondo le sezioni previste da Mokabyte, si creeranno delle classi ad hoc. Jena mette a disposizione il metodo createOntologyModel della classe factory ModelFactory. Per specificare il linguaggio è previsto il parametro con cui passare al metodo l’URI che definisce il linguaggio stesso, ad esempio ProfileRegistry.RDFS_LANG per RDFS (http://www.w3.org/2000/01/rdf-schema#), ProfileRegistry.OWL_DL_LANG per OWL-DL (http://www.w3.org/TR/owl-features/#term_OWLDL), e così via.
La classificazione nel MOKADIC viene definita nel seguente modo:
/**
The ontology model that holds the vocabulary terms
*/
private static OntModel rdfsModel =
ModelFactory.createOntologyModel(ProfileRegistry.RDFS_LANG);
/**
Categoria Java 2 Enterprise Edition
*/
public static final OntClass J2EE = rdfsModel.createClass( URI + “J2EE” );
/**
Categoria Java 2 Micro Edition
*/
public static final OntClass J2ME = rdfsModel.createClass( URI + “J2ME” );
. . . .
/**
Categoria Integrazione
*/
public static final OntClass J2SE = rdfsModel.createClass( URI + “J2SE” );
/**
Categoria Metodologia
*/
public static final OntClass J2SE = rdfsModel.createClass( URI + “J2SE” );
Da notare come queste classi potrebbero essere messe in gerarchia tra loro mediante il metodo addSubClass():
classJava.addSubClass(classeJumpStart);
A questo punto si procede alla creazione di triple RDF descrittive degli articoli Mokabyte:
// Creo una risora articolo J2EE Resource articoloResource1 = model.createResource("https://www.mokabyte.it/dd_mm_yyyy/ejb3.0") .addProperty(RDFS.label, "Esempio") .addProperty(RDFS.comment, "Un articolo moka J2EE") .addProperty(DC.publisher, "Mokabyte") .addProperty(DC.title, model.createLiteral("La specifica EJB 3.0", "it")) .addProperty(DC.creator, "Stefano Rossini") .addProperty(VCARD.EMAIL, "srossini@mokabyte.it") .addProperty(MOKADIC.hasJava, MOKADIC.J2EE) .addProperty(RDF.type, MOKADIC.resource);
Figura 12 – Grafo dell’esempio proposto (struttura flat).
Su tale RDF è possibile eseguire delle interrogazioni SPARQL; ad esempio, la seguente query permette di recuperare tutti gli articoli della sezione J2EE.
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX mokadic: <https://www.mokabyte.it/2007/06/moka_dic/1.0#> SELECT ?creatore ?titolo ?mail ?cat WHERE { ?article dc:creator ?creatore. ?article dc:title ?titolo. ?article vcard:EMAIL ?mail. ?article mokadic:hasJava ?cat. ?article mokadic:hasJava mokadic:J2EE }
Piuttosto che utilizzare tutte le proprietà in modo “piatto” (non strutturato), si può prevedere di “innestare” la risorsa dell’articolista in modo da avere una struttura più organizzata. Questo permette di ottenere una situazione più corretta rispetto alla precedente dove, in modo errato, è stata associata la proprietà VCARD.EMAIL all’articolo e non all’autore. Inoltre, sempre in modo strutturato, si intoduce una relazione tra autore e co-autore sfruttando FOAF.
// Creo la risorsa co-autore (A. Rocca) Resource alessandroRocca = model.createResource("https://www.mokabyte.it/arocca") .addProperty(FOAF.name,"Alessandro") .addProperty(FOAF.surname,"Rocca") .addProperty(FOAF.mbox,"arocca@mokabyte.it") .addProperty(RDF.type, FOAF.Person); // Creo la risorsa autore (S. Rossini) ed associo il co-autore con Resource stefanoRossini = model.createResource("https://www.mokabyte.it/srossini") .addProperty(VCARD.FN, "Stefano Rossini") .addProperty(VCARD.EMAIL, "srossini@mokabyte.it") .addProperty(FOAF.knows, alessandroRocca); // Creo la risorsa articolo Resource articoloResource = model.createResource("https://www.mokabyte.it/dd_mm_yyyy/ejb3.0") .addProperty(RDFS.label, "Esempio") .addProperty(RDFS.comment, "Un articolo moka J2EE") .addProperty(DC.creator, stefanoRossini) .addProperty(DC.publisher, "Mokabyte") .addProperty(DC.title, model.createLiteral("MDB: Message Driven EJB", "it")) .addProperty(MOKADIC.hasJava, MOKADIC.J2EE) .addProperty(RDF.type, MOKADIC.tipoMokaArticoloResource);
La serializzazione che si ottiene è la seguente:
<rdf:RDF xmlns_foaf="http://xmlns.com/foaf/0.1/" xmlns_rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns_rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns_vcard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns_moka="https://www.mokabyte.it/2007/06/moka_dic/1.0#" xmlns_dc="http://purl.org/dc/elements/1.1/" > arocca@mokabyte.it Rocca Alessandro ="https://www.mokabyte.it/2007/06/moka_dic/1.0#MokabyteArticle"/> MDB: Message Driven EJB Mokabyte Un articolo moka J2EE Esempio srossini@mokabyte.it Stefano Rossini
con il corrispondente grafico:
Figura 13 – Grafo dell’esempio proposto (struttura innestata)
Conclusioni
In questo articolo si è parlato e “toccato con mano” l’importanza di utilizzare i vocabolari esistenti e di crearne uno nuovo solo se necessario per soddisfare le proprie specifiche esigenze. Nel prossimo articolo inizieremo a parlare di ontologie e di Web Ontology Language (OWL).
Riferimenti
[MOKA_SEMW_1] A. Rocca – S. Rossini: “Semantic Web. I parte: Introduzione a RDF, principi e Data Model”, MokaByte 119, Giugno 2007
[WP_VCARD]
http://en.wikipedia.org/wiki/VCard
[W3CVS] W3C Validation Service
http://www.w3.org/RDF/Validator/direct
[WP_DC] Dublin Core
http://it.wikipedia.org/wiki/Dublin_Core
[DCME] Dublin Core Metadata Element Set, Version 1.1
http://dublincore.org/documents/dces/
[WP_FOAF]
http://en.wikipedia.org/wiki/FOAF
[FAM] FOAF-a-Matic
http://www.ldodds.com/foaf/foaf-a-matic
[FJ] FOAF.java
http://dev.w3.org/cvsweb/java/classes/org/w3c/rdfpic/vocabulary/#dirlist
[IMC] Internet Mail Consortium
http://www.imc.org/pdi/
[DCI] Dublin Core Metadata Initiative
http://dublincore.org/
[WP_DOAP] Description Of A Project
http://en.wikipedia.org/wiki/DOAP
[WP_WORDNET]
http://en.wikipedia.org/wiki/WordNet
[ASW] Altova Semantic Works 2007
http://www.altova.com/download/semanticworks/semantic_web_rdf_owl_editor.html