Database relazionali e loro integrazione con RDF/SPARQL

12
1 Database relazionali e loro integrazione con RDF/SPARQL Rosario Turco In questo articolo mettiamo in evidenza le potenzialità che può offrire OWL per mettere d’accordo, in tempo reale, due database relazionali attraverso le D2RQ interface e avere la possibilità di disporre di metadati ontologici separati dai dati. L’obiettivo dell’articolo è di mostrare situazioni in cui OWL è l’unica soluzione, permettendo di usare software open source e di sviluppare in sostanza poco software (ad esempio un XSLT). Supponiamo che esista l’esigenza di dover mantenere  due database distinti e che non si voglia un terzo database di raccordo, con tecniche ETL; ma in ogni caso serve effettuare delle query, in tempo reale, che tengano conto dei dati di entrambi i database ed i dati semanticamente uguali sono denominati in modo diverso. Come vedremo, tale esigenza è copribile solo con ontologie OWL e query SPARQL. Per fare un esempio pratico, supponiamo di caricare su MYSQL (installatevelo per l esempio) una collezione di dati provenienti da Outlook e da Eudora, dati che, magari, sono statu estratti con degli script Python e esportati su dei file di estensione csv. Notoriamente Outlook ed Eudora hanno address book e nomi di campi differenti. In APPENDICE c’è lo script che potete ricavare per la creazione dei due Database ed il caricamento dei dati in formato csv di esempio. Se creassimo solo i due database, noteremmo che esiste una evidente difficoltà nell’aggregare i dati e rispondere a domande particolari, in tempo reale, come listare tutti i numeri possibili (mobile, phone etc) di una persona, oppure ricavare tutte le informazioni di Bobby Fisher che abita al 2304 Eight Lane e che nell’altro database è scritto come Robert L. Fisher 8th Ln. L’idea di base in questo esempio è: 1) ottenere prima una rappresentazione RDF dei due database relazionali, sfruttando le D2RQ interface. 2) Con SWOOP editor generare automaticamente l’ontologia, mappare i campi dei due database 3) Ottenere la sintassi RDF/OWL per sfruttarla in futuro al variare dei dati 4) Sfruttare Pellet  e/o SPARQL per le query o il framework kbfe che li mette assieme Per poter ottenere tutto questo, serve un http-server che implementa le D2RQ interface; suggeriamo ad esempio l’utilizzo dell’efficace d2r-server (scaricatelo); il vantaggio è che d2r-server fornisce una serie di utility che implementano le D2RQ interface. In particolare le D2RQ interface permettono, attraverso un file di mapping, di tradurre la richiesta SPARQL ad una query per il database relazionale. Inoltre le D2RQ interface e d2r-server forniscono delle utility (generate-mapping) che generano il mapping in formato N3 (notation 3). Per l’esempio scaricate lo zip example.zip contenente i due csv dal link: https://docs.google.com/leaf?id=0BxVqe5c4FHDsNTljNDhmZWEtM2Y0Yy00MDU4LTkyOWUtNzY3ZTE1MzE 4MWRj&hl=en_US 

description

In questo articolo mettiamo in evidenza le potenzialità che può offrire OWL per mettere d’accordo, in tempo reale, due database relazionali attraverso le “D2RQ interface” e avere la possibilità di disporre di metadati ontologici separati dai dati.

Transcript of Database relazionali e loro integrazione con RDF/SPARQL

Page 1: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 1/11

 

1

Database relazionali e loro integrazione con RDF/SPARQL

Rosario Turco

In questo articolo mettiamo in evidenza le potenzialità che può offrire OWL per mettere d’accordo, in

tempo reale, due database relazionali attraverso le “D2RQ interface” e avere la possibilità di disporre di

metadati ontologici separati dai dati.

L’obiettivo dell’articolo è di mostrare situazioni in cui OWL è l’unica soluzione, permettendo di usare

software open source e di sviluppare in sostanza poco software (ad esempio un XSLT).

Supponiamo che esista l’esigenza di dover mantenere due database distinti e che non si voglia un terzo

database di raccordo, con tecniche ETL; ma in ogni caso serve effettuare delle query, in tempo reale, che

tengano conto dei dati di entrambi i database ed i dati semanticamente uguali sono denominati in modo

diverso. Come vedremo, tale esigenza è copribile solo con ontologie OWL e query SPARQL.

Per fare un esempio pratico, supponiamo di caricare su MYSQL (installatevelo per l’esempio) una collezione

di dati provenienti da Outlook e da Eudora, dati che, magari, sono statu estratti con degli script Python e

esportati su dei file di estensione csv. Notoriamente Outlook ed Eudora hanno address book e nomi di

campi differenti. In APPENDICE c’è lo script che potete ricavare per la creazione dei due Database ed il

caricamento dei dati in formato csv di esempio.

Se creassimo solo i due database, noteremmo che esiste una evidente difficoltà nell’aggregare i dati e

rispondere a domande particolari, in tempo reale, come listare tutti i numeri possibili (mobile, phone etc) diuna persona, oppure ricavare tutte le informazioni di Bobby Fisher che abita al 2304 Eight Lane e che

nell’altro database è scritto come Robert L. Fisher 8th Ln.

L’idea di base in questo esempio è:

1)  ottenere prima una rappresentazione RDF dei due database relazionali, sfruttando le D2RQ 

interface.

2)  Con SWOOP editor generare automaticamente l’ontologia, mappare i campi dei due database

3)  Ottenere la sintassi RDF/OWL per sfruttarla in futuro al variare dei dati

4)  Sfruttare Pellet e/o SPARQL per le query o il framework kbfe che li mette assieme

Per poter ottenere tutto questo, serve un http-server che implementa le D2RQ interface; suggeriamo ad

esempio l’utilizzo dell’efficace d2r-server (scaricatelo); il vantaggio è che d2r-server fornisce una serie di

utility che implementano le D2RQ interface.

In particolare le D2RQ interface permettono, attraverso un file di mapping, di tradurre la richiesta SPARQL

ad una query per il database relazionale. Inoltre le D2RQ interface e d2r-server forniscono delle utility

(generate-mapping) che generano il mapping in formato N3 (notation 3).

Per l’esempio scaricate lo zip example.zip contenente i due csv dal link:

https://docs.google.com/leaf?id=0BxVqe5c4FHDsNTljNDhmZWEtM2Y0Yy00MDU4LTkyOWUtNzY3ZTE1MzE

4MWRj&hl=en_US 

Page 2: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 2/11

 

2

Su MySQL create prima i due DB. come in appendice, eventualmente modificate il comando LOAD INFILE

DATA per puntare alla cartella dove metterete i due file csv che vi siete scaricati in example.zip. Poi

unzippate d2r_server.zip in C:. A questo punto vi consiglio di inserire una variabile d’ambiente

D2RQ_HOME che punta alla home e aggiungere a PATH anche %D2RQ_HOME%\bin

Ora possiamo metterci nella directory dei file csv e lanciare il comando che permette di creare i file di

mapping che ci servono:

%D2RQHOME%\generate-mapping –o eudoraMapping.ttl –u <user> -p <password>

jdbc:mysql://localhost:<port>/eudora

%D2RQHOME%\generate-mapping –o outlookMapping.ttl –u <user> -p <password>

jdbc:mysql://localhost:<port>/outlook

Al posto delle variabili <user>, <password> e <port> inserire i vostri valori del DB Mysql. Otterrete intanto

due file con estensione .ttl di mapping nella directory.

Adesso vediamo con d2r_server cosa possiamo fare con uno dei file di mapping prodotti. Innanzitutto

spostiamoci di directory:

cd %D2RQ_HOME%

Qui ci copiamo i file generati e poi facciamo il comando:

dr2-server eudoraMapping.ttf  

A questo punto possiamo usare il browser poter accedere al D2R server: http://localhost:2020/ 

Naturalmente 2020 è la porta di configurazione di default, se non l’avete cambiata; altrimenti usate quella

che avete configurato.

Page 3: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 3/11

 

3

Il D2R Server vi da la possibilità di esplorare le tabelle e il database, ma la cosa più interessante è la parte 3:

SPARQL Endpoint che vi dà più in basso il link “this AJAX -based SPARQL Explorer” che vi fa accedere ad un

browser SPARL per fare query (vedi figura).

La prima query di assaggio di solito è:

SELECT ?s ?p ?o WHERE {

?s ?p ?o .

}

Con cui otterrete la visualizzazione di un bel po’ di record. Ora gli possiamo chiedere qualcosa come: “

Fammi vedere tutte le informazioni di un telefonino che ha numero (328) 618-8442”, che in SPARQL va

tradotto in:

SELECT ?p ?o WHERE {

?s vocab:entries_mobile "(328) 618-8442" .

?s ?p ?o .

Quando lanciate la query, la sessione dove avete startato prima d2r-server con il file di mapping scrolla tutti

i record.

Page 4: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 4/11

 

4

Potremmo ripetere la stessa cosa per l’altro file di mapping, con un analogo comando differenziato per

quello che ci interessa; ma vedremmo solo i dati dell’altro e forse sono anche diversi. Quindi non ci rimane

che combinare opportunamente le due cose; ma come?

Serve creare un altro mapping che permetta di fare le query contemporaneamente su i due database.

Ognuno dei file di mapping precedente ha map: come prefix. Lo cambiamo in emap: in quello di eudora e

omap: in quello di outlook.

Un altro cambiamento utile è quello sostituire il prefix vocab: in eud: per il mapping eudora e in out: quellodi outlook e combiniamo i due file in uno solo (past & cut) che chiamiamo comboMapping.ttl ed eliminiamo

le duplicazioni.

Occorre stare attenti a mapping come questo:

emap:entries_email1 a d2rq:PropertyBridge;

d2rq:belongsToClassMap emap:entries;

d2rq:property eud:entries_email1;

# d2rq:column "entries.email1";

d2rq:uriPattern "mailto:@@entries.email1@@";

d2rq:condition "entries.email1 <> ''";

Se consultate il “D2RQ User Manual and Language Specification” [DR1] si capisce che le property sono un

bridge per legare colonne del DB con l’ RDF oppure in alternativa si possono usare le d2rq:uriPattern come

nell’esempio sopra e commentare le column. In questo secondo modo è più chiara la connessione tra i

diversi dati. Dire però a D2RQ di voler leggere una mail  [email protected]  non è però un URI; ecco perché

mettiamo anche il prefisso mailto:; inoltre però dobbiamo mettere anche la condizione che la stringa

entries.email1 non sia vuota, così non avremo nel caso di stringa vuota un mailto: da solo e inutile.

Dopo questo cambiamento occorre fare qualcosa di analogo per outlook nella parte

omap:entries_email2Address a d2rq:PropertyBridge;

d2rq:belongsToClassMap omap:entries;

d2rq:property out:entries_email2Address;

Page 5: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 5/11

 

5

# d2rq:column "entries.email2Address";

d2rq:uriPattern "mailto:@@entries.email2Address@@";

d2rq:condition "entries.email2Address <> ''";

A questo punto siamo pronti e facciamo:

cd %D2RQ_HOME% e copiamo qui comboMapping.ttl ed eseguiamo il comando:

dr2-server comboMapping.ttl  

Con delle prove potreste aver bisogno, come me, di commentare in due diversi punti:

#jdbc:autoReconnect "true";

#jdbc:zeroDateTimeBehavior "convertToNull";

Ora siamo in grado di fare query SPARQL, come prima con Snorql (l’interfaccia Web).

Le D2RQ interface offrono anche una fantastica utility dump, che sfruttiamo per generare dati caricabili poi

da un editor come SWOOP:

cd %D2RQ_HOME%

dump-rdf – m comboMapping.ttl –  f RDF/XML – o datadump.rdf 

Per l’help digitare dump-rdf a vuoto. Dateci un’occhiata che è utile. Ho dovuto usare –f per ottenere un file

caricabile da SWOOP. Fate partire SWOOP adesso. Fate File->Load->Ontology e caricate datadump.rdf 

Ora salviamolo con Save AS con nome postSwoop.rdf e confrontiamo quello che abbiamo ottenuto con

datadump.rdf: SWOOP ci ha creato una semplice ontologia, aggiungendo OWL dichiarazioni come:

<owl:DatatypeProperty rdf:about="&eudora;entries_address"/><owl:DatatypeProperty rdf:about="&eudora;entries_city"/>

<owl:DatatypeProperty rdf:about="&eudora;entries_country"/>

<owl:DatatypeProperty rdf:about="&eudora;entries_fax"/>

Page 6: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 6/11

 

6

Enrichement ontologico: le equivalenze colonne - uno a uno (mapping)

A questo punto si potrebbe usare SWOOP per arricchire l’ontologia per quando si faranno query SPARQL.

Ad esempio, iniziamo a dire che la colonna workState del DB eudora è equivalente alla colonna

businessState del Db outlook. Vediamo come.

Su SWOOP a sinistra a metà pagina, clicchiamo sul tab Property Tree e troviamo entries_workState. A

destra c’è il tab RDF/XML dove si vede la rappresentazione owl:DatatypeProperty di workState e dice tra

l’altro anche a quale file di provenienza è associato . Ritorniamo al Concise Format. Selezionando sempreentries_workState da Property Tree, cliccate su Editable in alto a destra e poi su Equivalent to: per creare il

mapping o l’equivalenza scegliendo il campo di outlook entries_businessState e fare Apply_Changes.

Ora salviamo l’ontologia o con Save As oppure con Ctrl-S. Riguardate il file postSwoop.rdf vedrete che c’è il

cambiamento di quest’ultima cosa. Cercate workState e vdrete l’aggiunta dell’equivalente. 

Page 7: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 7/11

 

7

Ovviamente si possono fare anche altre integrazioni come eudora:entries_firstName equivalente a 

outlook:entries_firstName, eudora:entries_lastNameequivalente a outlook:entries_lastName, etc.

Enrichment ontologico: equivalenze semantiche

Un’altra cosa che potrebbe essere utile per individuare tutti i numeri di telefono di Adams è di indicare che

tutte le phone properties hanno la semantica in comune. Vediamo come: basta creare una nuova phone

properties e tutte le altre metterle come sotto proprietà. Clicchiamo a sinistra su Add P. Sulla dialog box

selezionare OWL Datatype Property (è una stringa), poi Sub-property-of a None, come ID mettiamo phone

e facciamo Add & Close. Selezioniamo phone e facciamo adesso SuperProperty Add e mettiamo come sotto

proprietà le seguenti:

entries_businessFax entries_businessPhone entries_businessPhone2 entries_carPhone entries_homeFax entries_homePhone 

entries_homePhone2 entries_mobile entries_mobilePhone entries_otherPhone entries_phone entries_primaryPhone entries_workMobile 

Fate Apply Changes. Non lo dimenticate. Ora ci rimane di fare un’altra cosa: dobbiamo far capire al

Reasoner Pellet dopo che Bobby Fisher e Robert L. Fisher sono la stessa persona.

Noi abbiamo le properties emap:entries_email1 e out:entries_email2Address (basta guardare il tab

RDF/XML in corrispondenza dei campi nel Property Tree), che è già metà dell’opera. Ora basta aggiungere

che si tratta di funzioni inverse e che, quindi, poiché l’email sarà uguale per emap: e out: allora Robert L.

Fisher è equivalente a Bobby Fisher. Selezioniamo entries_email1 e facciamo a destra Inverse of Add e

mettiamo esntries_email2Address. Apply Changes. Facciamo ancora Ctrl-S e salviamo il file ottenuto.

In realtà su questo file si possono già fare query, non necessariamente con d2r_server, ma anche con il

 framework kbfe.

Però noi vogliamo anche che l’ontologia la possiamo usare anche per gestire nuove versioni dati del

database (anche se ci fossero dei cambiamenti), allora la strategia è di avere una ontologia che non fa

riferimento ai dati (le istanze) a cui va associata un file rdf in cui ci sono i dati.

In tal caso dobbiamo usare un editor per eliminare le parti che SWOOP genera sull’istanze (valorizzazione

delle classi); in particolare va tagliata la parte sotto <!-- Instances --> e salvare il file come  properties.owl 

Ora immaginiamo che i dati su MYSQL hanno subito delle modifiche (update). Occorre allora riottenere il

file datadump.rdf come prima e sfruttare properties.owl per fare le query SPARQL; ma la query va fatta su

un file merge dei due e che chiameremo combo.rdf. Come facciamo il merge? Nel nostro esempio per

semplificare, usiamo il datadump di prima (il concetto non cambia) e per combinare i due file ci creiamo un

XSLT di trasformazione rdfcat.xsl (vedi APPENDICE) in modo che quando lo lanciamo otteniamo un solo file

RDF combinato. Vedi la riga xsltproc &dash;&dash;xinclude rdfcat.xsl rdfcat.xml > combo.rdf che equivale a: 

xsltproc --xinclude rdfcat.xsl rdfcat.xml > combo.rdf

Page 8: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 8/11

 

8

Per poter fare queste operazioni è necessario installare xsltproc su Windows (vedi

http://www.zlatkovic.com/libxml.en.html  o da http://xmlsoft.org/XSLT/downloads.html  )

In questo caso combo.rdf è l’unione che ci serviva delle ontologie e dei due DB e possiamo fare adesso le

query su esso.

Riferimenti

[DR1] http://www4.wiwiss.fu-berlin.de/bizer/d2rq/spec/20061030/ 

APPENDICE

Creazione dei 2 DB e caricamento dei cvs

Comando da usare:

mysql -u <user> --password=<Password> < createDatabase.sql

# Create two address book databases and load data into them.

# No warrantee expressed or implied.

# In case they already exist...

#DROP DATABASE eudora;

#DROP DATABASE outlook;

CREATE DATABASE eudora;

USE eudora;

CREATE TABLE entries (

nickname VARCHAR(20),

email1 VARCHAR(50),

fullName VARCHAR(30),

firstName VARCHAR(15),

lastName VARCHAR(20),

address VARCHAR(60),

city VARCHAR(20),

state CHAR(2),

country CHAR(20),

zip CHAR(10),

phone CHAR(21),

fax CHAR(21),mobile CHAR(21),

web CHAR(70),

workOrganization VARCHAR(30),

workTitle VARCHAR(20),

workAddress VARCHAR(60),

workCity VARCHAR(20),

workState CHAR(2),

workCountry CHAR(20),

workZip CHAR(10),

workPhone CHAR(21),

workFax CHAR(21),

workMobile CHAR(21),

workWebAddress CHAR(70),otherEmail VARCHAR(50),

otherPhone VARCHAR(20),

otherWebPages VARCHAR(60),

Page 9: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 9/11

 

9

notes VARCHAR(256),

PRIMARY KEY (lastName,firstName)

);

LOAD DATA INFILE 'c:/owlrdbms/eudora.csv' INTO TABLE entries FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY

'\r\n';

CREATE DATABASE outlook;

USE outlook;

CREATE TABLE entries (

title VARCHAR(20),

firstName VARCHAR(15),

middleName VARCHAR(15),

lastName VARCHAR(20),

suffix VARCHAR(5),

company VARCHAR(30),

department VARCHAR(30),

 jobTitle VARCHAR(20),

businessStreet VARCHAR(30),

businessStreet2 VARCHAR(30),

businessStreet3 VARCHAR(20),

businessCity VARCHAR(20),

businessState VARCHAR(2),

businessPostalCode VARCHAR(10),

businessCountry VARCHAR(20),

homeStreet VARCHAR(30),

homeStreet2 VARCHAR(30),

homeStreet3 VARCHAR(20),

homeCity VARCHAR(20),

homeState VARCHAR(2),

homePostalCode VARCHAR(10),

homeCountry VARCHAR(20),

otherStreet VARCHAR(30),

otherStreet2 VARCHAR(30),

otherStreet3 VARCHAR(20),

otherCity VARCHAR(20),

otherState VARCHAR(2),

otherPostalCode VARCHAR(10),

otherCountry VARCHAR(20),

assistantsPhone CHAR(21),

businessFax CHAR(21),

businessPhone CHAR(21),

businessPhone2 CHAR(21),

callback CHAR(21),

carPhone CHAR(21),

companyMainPhone CHAR(21),homeFax CHAR(21),

homePhone CHAR(21),

homePhone2 CHAR(21),

ISDN CHAR(21),

mobilePhone CHAR(21),

otherFax CHAR(21),

otherPhone CHAR(21),

pager CHAR(21),

primaryPhone CHAR(21),

radioPhone CHAR(21),

TTYTDDPhone CHAR(21),

telex CHAR(21),

account VARCHAR(20),anniversary VARCHAR(20),

assistantsName VARCHAR(30),

billingInformation VARCHAR(30),

Page 10: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 10/11

 

10

birthday VARCHAR(20),

businessAddressPOBox VARCHAR(10),

categories VARCHAR(30),

children VARCHAR(40),

directoryServer VARCHAR(20),

emailAddress VARCHAR(50),

emailType VARCHAR(20),

emailDisplayName VARCHAR(50),

email2Address VARCHAR(50),

email2Type VARCHAR(20),

email2DisplayName VARCHAR(50),

email3Address VARCHAR(50),

email3Type VARCHAR(20),

email3DisplayName VARCHAR(50),

gender CHAR(1),

governmentIDNumber VARCHAR(20),

hobby VARCHAR(30),

homeAddressPOBox VARCHAR(10),

initials VARCHAR(3),

internetFreeBusy VARCHAR(20),

keywords VARCHAR(30),

language VARCHAR(5),

location VARCHAR(20),

managersName VARCHAR(30),

mileage VARCHAR(5),

notes VARCHAR(256),

officeLocation VARCHAR(20),

organizationalIDNumber VARCHAR(10),

otherAddressPOBox VARCHAR(10),

priority VARCHAR(3),

private CHAR(1),

profession VARCHAR(20),

referredBy VARCHAR(30),

sensitivity VARCHAR(16),

spouse VARCHAR(30),

user1 VARCHAR(20),

user2 VARCHAR(20),

user3 VARCHAR(20),

user4 VARCHAR(20),

webPage VARCHAR(60),

PRIMARY KEY (lastName,firstName)

);

LOAD DATA INFILE 'c:/owlrdbms/outlook.csv' INTO TABLE entries FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY

'\r\n';

RDFCAT.XSL

<!-- Assumes use of an XSLT processor with xinclude processor. For

xsltproc, run with xinclude parameter, e.g.

xsltproc &dash;&dash;xinclude rdfcat.xsl rdfcat.xml > combo.rdf

No warrantee expressed or implied.

--> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 

xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 

<xsl:strip-space elements="*"/> <xsl:output indent="yes"/> 

Page 11: Database relazionali e loro integrazione con RDF/SPARQL

5/6/2018 Database relazionali e loro integrazione con RDF/SPARQL - slidepdf.com

http://slidepdf.com/reader/full/database-relazionali-e-loro-integrazione-con-rdfsparql 11/11

 

11

<!-- The owl namespace declaration in the following is only here sothat it doesn't get added to each rdf:Description element. Toreally reduce the bulk of the output, add another namespacedeclaration after the xmlns:owl one for the namespace of theelements being replaced by the "*[@rdf:about]" template rule(the main namespace being output by d2r1). Without this, that

 

namespace declaration gets added to every single child of the

 

rdf:Description element. --> 

<xsl:template match="rdfcat"> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 

xmlns:owl="http://www.w3.org/2002/07/owl#"> <xsl:apply-templates /> 

</ rdf:RDF> </ xsl:template> 

<!-- Previous template rule covers the rdf:RDF element, so we don'tneed to copy it from the input to the output. --> 

<xsl:template match="rdf:RDF"> <xsl:apply-templatesselect="*"/> 

<!-- OWL DL software will want to see each resourceidentified as part of a class. --> 

<xsl:for-each select=" //@rdf:resource"> <!-- But don't bother with the ones in OWL, RDF, or RDFS elements. --> 

<xsl:if test="namespace-uri(..) != 'http://www.w3.org/2002/07/owl#' andnamespace-uri(..) != 'http://www.w3.org/2000/01/rdf-schema#' andnamespace-uri(..) != 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'"> 

<owl:Thing rdf:about="{.}"/> </ xsl:if> 

</ xsl:for-each> 

</ xsl:template> 

<!-- OWL DL software will want to see the classof each subject identified. --> 

<xsl:template match="rdf:Description[@rdf:about]"> <!-- If @rdf:about starts with #, make it a full URL. --> <xsl:variable name="rdfAboutPrefix"> <xsl:if test="substring(@rdf:about,1,1) = '#'"> <xsl:text>http://localhost/addressbook</ xsl:text> 

</ xsl:if> </ xsl:variable> 

<rdf:Description rdf:about="{$rdfAboutPrefix}{@rdf:about}"> <rdf:type> 

<owl:Class rdf:about="{local-name()}"/> </ rdf:type> <xsl:apply-templatesselect="node()"/> 

</ rdf:Description> </ xsl:template> 

<xsl:template match="rdf:Descriptin"> <xsl:apply-templates /> 

</ xsl:template> 

<!-- Just copy everything else verbatim. --> 

 

<xsl:template match="@*|node()"> <xsl:copy> 

 

<xsl:apply-templatesselect="@*|node()"/> </ xsl:copy> 

</ xsl:template> 

</ xsl:stylesheet>