Comincia una serie sul Semantic Web che ha lo scopo di presentarne gli aspetti tecnici e le tecnologie. Analizzeremo le varie componenti del Semantic Web Stack, presentando di volta in volta degli esempi. In questo primo articolo della serie, ci occupiamo di RDF.
Introduzione
Abbiamo già parlato di Semantic Web in diverse occasioni, tra le quali l‘articolo introduttivo [MOKA_SW]. Cominciamo questo numero una serie di articoli dedicati a questo argomento, affrontandone aspetti teorici e pratici che concorrono a darne una visione piuttosto completa, ai diversi livelli.
Anzitutto va ribadito che con l‘espressione “Semantic Web” si intende un insieme di tecnologie che hanno l‘obiettivo di rendere le informazioni comprensibili ed elaborabili da parte di programmi: in pratica lo scopo sta nel permettere a “macchine” (intese come infrastrutture e applicazioni sofware) di creare nuova conoscenza traendo delle conclusioni a partire dalla base di conoscenza iniziale.
Per quanto riguarda standard e tecnologie, il Semantic Web va inteso come una struttura “a gradini”: uno “stack” tecnologico formato da più componenti in cui ogni livello è la base per gli standard definiti ai livelli superiori.
In questo primo articolo si parlerà di RDF, Description Framework. Si affronterà l‘argomento sia da un punto di vista teorico che pratico.
Resource Description Framework
RDF è l‘acronimo di Description Framework, uno standard XML del W3C [W3CRDF] la definizione di un modello di rappresentazione di metadati, il cui compito è promuovere l‘interoperabilità tra applicazioni basata sullo scambio sul Web di informazioni comprensibili dalle macchine (“machine understandable”).
L‘RDF si basa su XML (XML, XML schema e namespace), URI e Unicode. Di seguito si riporta una breve descrizione di ciascuno di questi elementi.
URI e unicode
URI è l‘acronimo di Uniform Resource Identifier [WP_URI] ossia una stringa che identifica univocamente una risorsa generica. Tale risorsa può essere un indirizzo web, un documento, un‘immagine, un file, un servizio, un indirizzo di posta elettronica.
Gli URL, Uniform Resource Locator [WP_URL], sono un sottoinsieme degli URI. Mediante URL si identificano risorse specifiche della rete, come ad esempio pagine web, immagini, etc., facendo riferimento alla loro localizzazione e mettendo in evidenza la modalità di accesso (il protocollo).
L‘Unicode [WP_UNICODE] è invece un sistema di codifica che assegna un numero (o meglio, una combinazione di bit) a ogni carattere in maniera indipendente dal programma, dalla piattaforma e dalla lingua (e dal suo sistema di scrittura).
Da XML a RDF
XML (eXtensible Markup Language) è un metalinguaggio che permette di definire sintatticamente linguaggi di mark-up [XML]. Nato come linguaggio utile allo scambio dei dati, permette di esplicitare la struttura, quindi la sintassi, di un documento in modo formale mediante marcatori (mark-up) che vanno inclusi all‘interno del testo.
Per definire la struttura di un documento XML, o più precisamente la grammatica che tale documento deve rispettare, esistono linguaggi quali DTD e XML Schema [XSD]. Entrambi sono strumenti per eseguire la validazione del documento XML. Ad esempio XSD (XML Schema Definition) permette di specificare vincoli sia strutturali che di contenuto ed è a tutti gli effetti un linguaggio XML.
XML si “limita” a descrivere dati senza entrare nel merito della semantica contenuta. Un documento XML rispecchia la classica struttura ad albero (gerarchica), all‘interno del quale le informazioni sono correlate secondo una relazione di subordinazione (classificazione). Nei documenti XML, i dati riportati acquistano un loro significato dettato esclusivamente da un modello gerarchico/classificatorio la cui interpretazione è a discrezione umana e non è comprensibile dalla macchina, non essendo presente un esplicito formalismo di definizione della classificazione.
Dalla figura 3 si nota come, nel classificare le informazioni secondo una struttura ad albero, siano state implicitamente inserite relazioni del tipo IS_A e IS_PART_OF, semanticamente dedotte secondo logica umana, in funzione dei nomi dei tag e del livello di annidamento degli elementi.
Per l‘interrogazione di documenti XML, il W3C ha introdotto XQuery [XQuery]. XQuery (XML Query language) non è un linguaggio basato su XML, ma è costituito da una sintassi semplice e facilmente leggibile per formulare le query sui dati. Le espressioni XQuery sono basate su XPath [XPath] data model, ovvero strutture dati ordinate nell‘ordine in cui appaiono nel documento XML sorgente (document order). Anche XPath non è un linguaggio XML e permette di individuare i nodi all‘interno di un documento XML. Le espressioni XPath, a differenza delle espressioni XML, non servono a identificare la struttura di un documento, bensì a localizzarne con precisione i nodi.
Essendo basato su XPath, XQuery è fortemente legato alla struttura del documento. Ad esempio per recuperare i nomi degli autori che hanno partecipato alla stesura di questo articolo, la query risulta dipendente dalla struttura XML con cui si censiscono gli articoli.
Data la natura modulare di XML, al fine di evitare possibili ambiguità dovute all‘uso di entità aventi lo stesso nome, è stato introdotto il concetto di namespace [XMLNS]. Un namespace associa un contesto di appartenenza all‘entità utilizzata, garantendone l‘univocità durante il processo di validazione da parte del Parser XML. Oltre a risolvere il problema dell‘ambiguità , l‘utilizzo dei namespace rende la scrittura del codice più sintetica e quindi meglio leggibile.
Ad esempio:
xmlns:xsd=http://www.w3.org/TR/REC-xml-names/
referenzia il namespace standard della sintassi XMLSchema, associando al termine
xsd
il contesto
http://www.w3.org/TR/REC-xml-names/
Di fatto, ogni volta che nel documento XML si incontra il termine xsd: seguito dal nome di una entità , si deve (mentalmente) intendere tale entità come appartenente al namespace dichiarato precedentemente.
Dopo avere parlato di XML, XSD, XQuery e XPath e namespace, veniamo al nocciolo dell‘articolo: iniziamo a parlare di RDF.
Perchè RDF?
Ad oggi, l‘informazione fruibile, contenuta all‘interno di una qualsiasi risorsa, è strutturata in modo da essere “machine-readable” (leggibile da una macchina) ma non “machine-understandable” (comprensibile da una macchina). La mancanza di una caratterizzazione semantica, ossia sul significato deducibile, pone infatti un limite nelle operazioni di elaborazione automatica delle informazioni sul web.
Per colmare le lacune che impediscono alla macchina di interpretare l‘informazione possono essere utilizzati metadati, cioè descrizioni aggiuntive ai dati. Questa è appunto la funzione di RDF, il quale introduce un formalismo per la rappresentazione di metadati basato sul concetto di “statement” (asserzioni) codificati in triple: soggetto-predicato-oggetto.
In questo modo RDF (che è un‘implementazione di XML) introduce maggiore capacità espressiva permettendo di definire diverse tipologie di relazione secondo un modello relazionale/predittivo. L‘idea è quella di poter utilizzare una struttura dati organizzata secondo un grafo orientato: sui nodi ti questo grafo sono poste le risorse (soggetto e oggetto dello statement), mentre gli archi del grafo rappresentano le relazioni (predicato dello statement). È possibile così aggiungere connessioni (relazioni) tra molteplici risorse, permettendone l‘estensione della conoscenza.
Tornando all‘esempio precedente, attraverso RDF è possibile esplicitare le relazioni che intercorrono fra le varie entità per cui un uomo, oltre a essere un mammifero e possedere gambe e braccia, può essere proprietario di un cane. Quindi la struttura ad albero precedente viene trasformata nel seguente grafo orientato.
Il grafo è una generalizzazione dell‘albero. Ogni nodo ha un numero arbitrario di nodi “vicini” e può contenere cicli. In generale, può essere associata un‘informazione utile sia ai nodi che ai collegamenti (archi). specifica di RDF è costituita da due componenti: RDF Model and Syntax e RDF Schema.
RDF Model and Syntax
RDF Model and Syntax definisce il data model RDF (modello dei dati), che descrive le risorse e la sintassi XML utilizzata per specificare tale modello. Non definisce alcun livello di gerarchia o di relazione. Il modello è basato su tre oggetti:
Resource (risorsa): indica ciò che viene descritto mediante RDF e può essere una risorsa Web (ad esempio una pagina HTML, un documento XML o parti di esso) o anche una risorsa esterna al Web (ad esempio un libro, un quadro, etc.). Una Resource è una qualunque entità associabile a un‘URI.
Property (proprietà / predicato): indica una proprietà , un attributo o una relazione utilizzata per descrivere una risorsa. Il significato e le caratteristiche di questa componente vengono definite tramite RDF Schema.
Statement (asserzione o espressione): è l‘elemento che descrive la risorsa ed è costituito da un soggetto (che rappresenta la Resource), un predicato (che esprime la Property) e da un oggetto (chiamato Value) che indica il valore della proprietà . La struttura di uno statement (asserzione) RDF è composta di una tripla, ovvero da un Soggetto, un Predicato e un Oggetto (o, equivalentemente, Risorsa – Proprietà – Valore).
RDF statement
Come appena detto, in RDF, la logica dei predicati, le informazioni sono esprimibili con asserzioni (statement in inglese) costituite da triple formate da:
- Soggetto: ciò di cui si parla
- Predicato: è la proprietà , l‘attributo, la caratteristica che si vuole descrivere
- Oggetto: è il valore della proprietà
Ad ogni tripla è associabile un grafo, dove ogni elemento è identificato da un URI. Lo standard prevede anche una notazione grafica per le asserzioni RDF: graficamente una risorsa viene rappresentata con un un‘ellisse, le proprietà vengono rappresentate come archi etichettati e i valori corrispondenti a sequenze di caratteri vengono rappresentati come rettangoli.
Un esempio di asserzione RDF è:
“Stefano Rossini ha indirizzo e-mail srossini@mokabyte.it”
che corrisponde al seguente tracciato RDF:
<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#" > ÃÂ https://www.mokabyte.it/StefanoRossini"> ÃÂ ÃÂ srossini@mokabyte.it ÃÂ
dove:
soggetto: Stefano Rossini (https://www.mokabyte.it/StefanoRossini)
predicato: ha indirizzo e-mail ()
oggetto: la costante literal indicante l‘indirizzo e-mail (srossini@mokabyte.it)
Il tag è l‘elemento root del documento RDF, indentifica una risorsa con l‘attributo about che definisce la risorsa descritta.
Altri attributi importanti RDF sono , e .
Volendo fare “un‘analogia didattica” tra la rappresentazione dei dati RDF e il Entity-Relationship dei database relazionali, si può dire che:
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 quanto riguarda la rappresentazione fisica, un grafo RDF può essere serializzato in diversi modi. Le principali serializzazioni adottabili per un grafo RDF sono:
XML: RDF serializzato in un file XML
N-TRIPLE: serializzato come insieme di triple soggetto-predicato-oggetto [N-TRIPLE]
N3 (Notation 3): si serializza il grafo descrivendo, una per volta, una risorsa e tutte le sue proprietà [N3]
TURTLE: Terse RDF Triple Language, un‘estensione di N-Triple [TURTLE]
RDF Schema
Il puro RDF serve unicamente per descrivere modelli di dati e può esprimere semplici affermazioni come “il nome del mio cane è Aran”, “un cane è un animale”, “un particolare cane è Pastore Tedesco” e così via. Tuttavia, quando si usa RDF per descrivere gli oggetti di un particolare dominio (le razze canine ad esempio), è indispensabile tenere conto della natura stessa del dominio. In pratica l‘ambito interessato va considerato in termini “reali”: le categorie (classi di oggetti appartenenti al dominio), le relazioni possibili tra gli oggetti, le regole che governano queste relazioni devono possedere certe caratteristiche per risultare “valide”.
RDF Schema permette di definire il significato e le caratteristiche delle proprietà e delle relazioni che esistono tra queste e le risorse descritte nel data model RDF. RDF Schema fornisce un insieme di risorse e proprietà predefinite. L‘insieme delle risorse e delle relative proprietà di base è detto “vocabolario” dell‘RDF Schema. Attraverso tale vocabolario base è possibile definire specifici vocabolari per i metadati e creare relazioni tra oggetti.
I concetti messi a disposizione da RDF Schema sono quelli di
- Classe e SottoClasse
- SottoProprietà
- Dominio e Codominio di una Proprietà
- Commenti, Etichette e Informazioni Addizionali (“SeeAlso”)
Attraverso uno Schema RDF è possibile assegnare un significato ai vari termini utilizzati nelle asserzioni RDF; una risorsa può, per esempio, essere definita come istanza di una classe (o di più classi) e le classi possono essere organizzate in modo gerarchico, permettendo di derivare, per ereditarietà , nuova conoscenza. Inoltre fornisce un meccanismo di specializzazione delle proprietà , definendone i vincoli d‘applicabilità e organizzandole gerarchicamente. questo modo è possibile aggiungere connessioni (relazioni) tra molteplici risorse permettendone di fatto l‘estensione del significato (semantica).
I principali costrutti sono , , , , che consentono di organizzare in tassonomie le classi e le relazioni (Properties) del dominio a seconda della loro generalità .
RDF Schema arricchisce RDF attraverso un semplice sistema di tipi.
Volendo fare “un‘analogia didattica” tra RDFS e la programmazione object oriented (OOP), si può dire:
Nell‘OO si definiscono le classi che rappresentano una descrizione di una categoria di oggetti, individuati da comportamenti e caratteristiche simili, i relativi comportamenti vengono definiti “metodi” mentre le caratteristiche sono delle “proprietà “. Le classi possono essere estese per ereditarne dati e comportamenti (relazione IS-A) e gli oggetti sono istanze di classi.
RDFS prevede anch‘esso la creazione di classi e l‘ereditarietà ma non prevede la definizione di metodi visto che è orientato alla modellazione dei dati e non al comportamento di questi ultimi.
È importante evidenziare che in RDF le descrizioni delle proprietà sono indipendenti dalla definizione della classe (al contrario, in OOP la definizione di una proprietà è ristretta alla classe): potremmo quindi definire il sistema di tipizzazione RDF come modello “Property-Oriented”.
Più che contenitori, le classi RDFS sono dei descrittori (concetti o proprietà ) in relazione semantica tra di loro. Nei prossimi numeri vedremo come definire un Vocabolario utilizzando RDFS e un‘Ontologia con OWL.
Per utilizzare le basi di conoscenza formalizzate secondo questi standard RDF è necessario un linguaggio per interrogarle. Esistono diversi linguaggi di interrogazione funzionalmente equivalenti: SPARQL, RDQL, RQ, etc. ai linguaggi concepiti per l‘interrogazione di documenti XML, le query hanno il grosso vantaggio di essereÃÂ indipendenti dalla struttura del documento perché formalmente le informazioni in un documento RDF vengono rappresentate come triple soggetto-predicato-oggetto. Il linguaggio permette di costruire query basate su triple e applicarle al modello dei dati. Interrogare un documento RDF significa quindi selezionare una risorsa in funzione del verificarsi di opportune proprietà su essa (viene rimarcata l‘analogia con il data model relazionale).
SPARQL
SPARQLÃÂ è una specifica sviluppata W3C RDF Data Access Working Group a supporto dell‘interrogazione dei documenti RDF. La stessa specifica si suddivide in due ulteriori specifiche SPROT (definisce il protocollo di esecuzione delle query e la relativa ricezione dei risultati) e RESULTS (definisce il formato del risultato di una query).
Le query SPARQL adottano la sintassi Turtle e si basano sul meccanismo di “pattern matching” e in particolare su un costrutto, il “triple pattern”, che ricalca la configurazione a triple delle asserzioni RDF fornendo un modello flessibile per la ricerca di corrispondenze. Riprendendo come esempio lo statement definito precedentemente:
“Stefano Rossini ha indirizzo e-mail srossini@mokabyte.it”
il triple pattern corrispondente è il seguente:
?nomeÃÂ ha indirizzo e-mailÃÂ ?e-mail
Al posto del soggetto e dell‘oggetto questo “triple pattern” prevede due variabili, contrassegnate con ?nomeÃÂ ÃÂ edÃÂ ÃÂ ?e-mail. Le variabili rappresentano le incognite dell‘interrogazione mentre il predicato “ha indirizzo e-mail” rappresenta una costante.
Data una base dati RDF, le triple (statement) che trovano riscontro nel modello definito dal triple pattern associeranno i propri termini alle variabili corrispondenti. In pratica vengono presi in considerazione tutti e solo gli statement che contengono il predicato “ha indirizzo e-mail”.
Definito il modello su cui le query SPARQL si basano, diamo un‘occhiata veloce alla sintassi delle query:
SELECT FROM WHERE {. }
Come si nota, vi è un‘analogia con SQL: nella clausola SELECT vengono elencate le variabili da valorizzare ai fini del risultato, nella clausola FROM viene definita la base dati, documento RDF, su cui eseguire la query, nella clausola WHERE vengono elencati, tra parentesi graffe, i criteri di selezione, ovvero i triple pattern.
Un esempio di query SPARQL sull‘asserzione precedente potrebbe essere:
ÃÂ SELECT ?nome ÃÂ WHERE ÃÂ ÃÂ ?nomeÃÂ ha indirizzo e-mailÃÂ ?e-mail ÃÂ }
Da notare che la variabile da valorizzare (?nome nella clausola SELECT) deve comparire anche come incognita di interrogazione (?nome clausola WHERE); in caso contrario SPARQL non sarebbe in grado di valorizzarla.
Jena
Jena è un framework Java open source (sviluppato dal Semantic Web Research Bristol Lab della HP) per lo sviluppo di applicazioni orientate al Web Semantico [JENA]. EssoÃÂ fornisce le API per la creazione, interrogazione e gestione in modo programmatico di RDF.
Vediamo come creare con le API Jena un elenco di asserzioni RDF relative agli articolisti di MokaByte che collaborano a queste serie tecniche dedicate al Web 2.0 e al Semantic Web.
Figura 10 – Esempio di creazione di un file RDF con le API Jena
Di fatto si crea un model (classe Model) mediante il metodo factoryÃÂ ModelFactory.createDefaultModel()ÃÂ e si aggiungono le varie risorse (gli articolisti MokaByte) e le proprietà nome, email e soprannome utilizzando il dizionario VCARD [WP_VCARD].
// creo un model Model model = ModelFactory.createDefaultModel();
// creo le risorse aggiungendogli a "cascata" per ognuna le proprietà VCARD d‘interesse 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"));
Resource alessandroRocca = model.createResource("https://www.mokabyte.it/AlessandroRocca") ÃÂ .addProperty(VCARD.FN, "Alessandro Rocca") ÃÂ .addProperty(VCARD.NICKNAME, "Blend") ÃÂ .addProperty(VCARD.N, model.createResource() ÃÂ .addProperty(VCARD.EMAIL, "arocca@mokabyte.it")); . . . . .
È possibile ottenere la lista degli statement contenuti nel Model mediante l‘oggetto di classe StmtIterator:
// Richiedo al model la lista degli statement contenuti StmtIterator iter = model.listStatements();
iterare sugli statement contenuto nel Model:
while (iter.hasNext()) { ÃÂ Statement stmtÃÂ ÃÂ = iter.nextStatement();// get next statement ÃÂ System.out.println("Statement ["+stmt.toString()+"]-");
e ottenere puntualmente il soggetto, il predicato e l‘oggetto dello statement:
ÃÂ ResourceÃÂ subjectÃÂ ÃÂ = stmt.getSubject();ÃÂ ÃÂ // richiedo il subject ÃÂ PropertyÃÂ predicate = stmt.getPredicate(); // richiedo il predicate ÃÂ RDFNodeÃÂ ÃÂ objectÃÂ = stmt.getObject();ÃÂ // richiedo l‘object ÃÂ if (object instanceof Resource) { ÃÂ ÃÂ << Resource >> ÃÂ } else { ÃÂ ÃÂ << Literal >> ÃÂ } }
Per trascrivere il contenuto del model RDF nei vari formati di serializzazione consentiti è possibile utilizzare il metodo write() della classe Model specificando l‘output stream su cui scrivere con il relativo formato (XML, N-TRIPLE o N3):
ÃÂ model.write(fileOutputStream); // XML ! ÃÂ model.write(fileOutputStream, "N-TRIPLE"); ÃÂ model.write(fileOutputStream, "N3");
Analogamente per leggere un documento RDF si può utilizzare il metodo read() sempre della classe Model
ÃÂ InputStream in = new FileInputStream(<< file name >>); ÃÂ model.read(in, "", "N3");
Oltre a recuperare tutte le risorse associate al Model mediante il metodo listStatements(), è anche possibile recuperare puntualmente le risorse dal model:
ÃÂ Resource resource = model.getResource("https://www.mokabyte.it/StefanoRossini");
oppure utilizzando delle opportune classi Selector:
ÃÂ StmtIteratorÃÂ iter = model.listStatements( ÃÂ ÃÂ new ÃÂ ÃÂ ÃÂ SimpleSelector(null, VCARD.FN, (RDFNode) null) { ÃÂ ÃÂ ÃÂ ÃÂ public boolean selects(Statement s) { ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ return s.getString().endsWith(" Rossini"); ÃÂ ÃÂ ÃÂ ÃÂ } ÃÂ ÃÂ ÃÂ });
Con Jena è possibile fare interrogazioni RDQL e SPARQL.
Di seguito si riporta un esempio di query SPARQL dove viene recuperato il nome e la email di tutti gli autori che hanno un soprannome, un nome e un indirizzo di posta elettronica. Per fare questa operazione basta dare “in pasto” all‘oggetto di classe Query la stringa relativa alla query, e indicare il Model su cui effettuare l‘interrogazione. Per eseguirla è sufficiente invocare il metodo execSelect().
String queryString= ÃÂ "PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>" + ÃÂ " PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>" +ÃÂ ÃÂ " SELECT ?fullname ?email" +ÃÂ ÃÂ " WHERE {" +ÃÂ ÃÂ "ÃÂ ÃÂ ?about vcard:NICKNAME ?nickname." + ÃÂ "ÃÂ ÃÂ ?about vcard:FN ?fullname." + ÃÂ "ÃÂ ÃÂ ?about vcard:N ?v_id." +ÃÂ ÃÂ "ÃÂ ÃÂ ?v_id vcard:EMAIL ?email" + ÃÂ " }"; Query query = QueryFactory.create(queryString);
// Execute the query and obtain results QueryExecution qe = QueryExecutionFactory.create(query, model); ResultSet results = qe.execSelect();
// Output query resultsÃÂ ResultSetFormatter.out(System.out, results, query);
// Important - free up resources used running the query qe.close();
Utilizzando il metodo statico out() della classe ResultSetFormatter, il risultato della query viene stampato sullo standard output:
----------------------------------------------- | fullnameÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ | emailÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ ÃÂ | =============================================== | "Stefano Rossini"ÃÂ | "srossini@mokabyte.it" | | "Alessandro Rocca" | "arocca@mokabyte.it"ÃÂ ÃÂ | -----------------------------------------------
Joseki: il Server RDF Jena
Joseki è un HTTP / SOAP engine che permette l‘invio di query SPARQL via HTTP [JOSEKI].
Figura 11 – Joseki
Di fatto Joseki permette di interagire con un Jena engine mediante il protocollo HTTP.
Avviare e utilizzare Joseki è semplice. Una volta configurata la variabile d‘ambiente JOSEKIROOT, è sufficiente lanciare lo script rdfserver indicando il file di configurazione (.ttl) da utilizzare. Con questa operazione viene avviato un HTTP server in ascolto sulla porta TCP 2020.
%JOSEKIROOT% in dfserver.bat file:C:installedJoseki-3.0joseki-config-example.ttl
Di default, Joseki permette di eseguire query via browser sull‘elenco dei dati contenuto nel file d‘esempio books.n3 (un elenco dei libri su Harry Potter!?). Lanciando il browser e collegandosi all‘URLÃÂ http://localhost:2020/ÃÂ viene visualizzzata una pagina Web con una Text Box nella quale è possibile digitare la query SPARQL che si vuole eseguire. Ad esempio con la seguente query SPARQL si richiedono tutti i libri che hanno un titolo. Il relativo risultato è presentato in una pagina HTML.
PREFIX books:ÃÂ <http://example.org/book/> PREFIX dc:ÃÂ <http://purl.org/dc/elements/1.1/> SELECT ?book ?title WHERE ÃÂ { ?book dc:title ?title }
Di fatto il client effettua una GET passando come parametro la query inserita nella Text Box; la relativa risposta HTTP di Joseki contiene il risultato della query opportunamente formattato in HTML.
Di seguito viene proposto l‘esempio di utilizzo di Joseki sul file RDF “moka authors” precedentemente creato con Jena. Per configurare Joseki in modo da puntare al nostro elenco dati mokauthors.n3 basta creare un nuovo file di configurazione (joseki-config-mokauhtors.ttl) nel quale indicare il file N3 contente i dati (gli statement RDF) su cui effettuare le interrogazioni:
@prefix rdfs:ÃÂ http://www.w3.org/2000/01/rdf-schema#> . @prefix rdf:ÃÂ <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix xsd:ÃÂ <http://www.w3.org/2001/XMLSchema#> . . . . # A dataset of one model as the default graph, data loaded from a file. _:booksÃÂ ÃÂ rdf:type ja:RDFDataset ; ÃÂ rdfs:label "Moka Authors VCards" ; ÃÂ a:defaultGraph ÃÂ ÃÂ [ rdfs:label "mokauthors.n3" ; ÃÂ ÃÂ a ja:MemoryModel ; ÃÂ ÃÂ ja:content [ja:externalContent <file:Data/mokauthors_vcards.n3> ] ; ÃÂ ] ÃÂ . . .
Lanciato Joseki con
%JOSEKIROOT% in dfserver.bat file:D:installedJoseki-3.0joseki-config-mokauthors.ttl
e collegandosi all‘URL localhost:2020, è possibile interrogare l‘elenco di autori MokaByte. Ad esempio, eseguendo la seguente query SPARQL, si recuperano il nome e la email di tutti gli autori che hanno un soprannome, un nome ed una mail:
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> SELECT ?fullname ?email WHERE { ÃÂ ?about vcard:NICKNAME ?nickname. ÃÂ ?about vcard:FN ?fullname. ÃÂ ?about vcard:N ?v_id. ÃÂ ?v_id vcard:EMAIL ?email }
Conclusioni
Dopo una breve analisi degli aspetti fondamentali del Semantic Web, in questo primo articolo della serie è stato affrontato il Resource Description Framework, introducendone i principi e il data model RDF. Nel prossimo articolo si proseguirà a parlare di RDF e RDFS in maniera più approfondita: affronteremo i dettagli dei vocabolari.
Riferimenti
[MOKA_SW] P.M Vignati, “Introduzione al Semantic Web”, MokaByte 116, Marzo 2005
[MOKA_WSS_1] S. Rossini, R. Spazzoli, “Web Services: il punto sulla standardizzazione (I)”, MokaByte 96, Maggio 2005
[W3CRDF]
http://www.w3.org/RDF
[WP_RDF]
http://it.wikipedia.org/wiki/RDF
[RDF-PRIMER]
http://www.w3.org/TR/rdf-primer
[DACSW] M.C. Daconta – L.J. Obrst – K. T. Smith, “The Semantic Web: A Guide to the Future of XML, Web Services, and Knowledge Management”, John Wiley & Sons
[XML]
http://www.w3.org/XML/
[XMLNS]
http://www.w3.org/TR/REC-xml-names/
[XSD]
http://www.w3.org/XML/Schema
[XQUERY]
http://www.w3.org/XML/Query
[XPATH]
http://www.w3.org/TR/xpath
[WP_UNICODE]
http://it.wikipedia.org/wiki/Unicode
[WP_URI]
http://it.wikipedia.org/wiki/Uniform_Resource_Identifier
http://www.w3.org/TR/uri-clarification/
[WP_SW] Wikipedia Semantic Web
http://en.wikipedia.org/wiki/Semantic_web
[WP_VCARD]
http://en.wikipedia.org/wiki/VCard
[SPARQL] SPARQL Query Language for RDF
http://www.w3.org/TR/rdf-sparql-query/
[JENA]
http://jena.sourceforge.net/
[JENA_DOCS] Jena Documentation
http://jena.sourceforge.net/documentation.html
[JOSEKI] Joseki, a SPARQL Server for Jena
http://www.joseki.org/
[TURTLE]
http://www.dajobe.org/2004/01/turtle/
[N3]
http://www.dajobe.org/2003/11/ntriplesplus/#ref-n3
[N-TRIPLE]
http://www.dajobe.org/2003/11/ntriplesplus/#ref-ntriples