Zápisky.info
Zveřejníme akademické projekty, samozřejmě sémanticky
Sémantický web, RDF a další příbuzné technologie nemusí být jen hračkou pro akademiky a nástrojem pro pokročilé analyzování informací. Vyvíjím webovou prezentaci pro Knowledge Engineering Group, uskupení výzkumníků při VŠE Praha, kteří se zajímají o znalostí inženýrství. Vsadil jsem na PHP jako framework, na RDF jako datový model a vidím v tom výhody. Aktuálně dokončuji seznam akademických projektů, na kterých se tato skupina podílí a proto následujícím tutoriálem předvedu, jak lehce lze s RDF pracovat využít jej jako interní datový model ve webové aplikaci. Chcete–li před čtením toto článku absolvovat lehký úvod do sémantických webových technologií, přečtěte si Parsování FOAF s PHP, překlad tutoriálu pro jeden z RDF frameworků, které je možné využít ve skriptovacím jazyce PHP. Pro náš aktuální příklad ale budeme pracovat s jiným — ARC2.
Tvorba schématu trochu jinak
Jednou z věcí, na kterou si u RDF musíte zvyknout, jen datový model. Nepracujete s tabulkami, sloupci a řádky. Máte k dispozici graf trojic. A co víc, RDF nemá ani jeden normativní formát, do kterého tyto data zapisovat. Pracovat můžete s XML (RDF/XML), stejně jako třeba N–Triples, Notation 3 a nebo si můžete graf namalovat. U relačních databází musíte napřed vytvořit schéma, uložit počáteční data a pak s ním můžete pracovat. Ukážeme si, jak se modeluje schema pro RDF–aplikaci. V příkladech budeme používat syntaxi N3. Tak jako jsou v relačních databázích záznamy (řádky), jsou v RDF zdroje. Každý zdroj má tvar URI (URL, FTP, LDAP, e–mail, telefon…) a může existovat bez jakýchkoliv dalších podrobností. Tato URI je zároveň ekvivalentem primárního klíče v databázích.
Proto si v našem grafu vytvoříme jeden pomyslný zdroj. Ty se v N3 syntaxi zapisují do špičatých závorek.
<http://example.com/resource/1>
V této chvíli začal zdroj existovat, ale nevíme o něm nic. Tyto informace doplníme pomocí trojic tzv. tvrzení, které o něm vytvoříme. Budeme však potřebovat ono v úvodu zmiňované schéma. Budete se možná divit, ale všechny pojmy v RDF jsou popsány také RDF. Proto existuje základní slovník RDF, slovník RDF Schema pro vytváření dalších schemat a dále mnoho slovníků pro konkrétní oblasti použití – knihovnické pojmy, sociální sítě, kalendář, kontakty nebo třeba slovník pro popis druhů whisky. Vždy se vyplatí hledat již existující slovník a pokud vám vyhovuje, použít jej. Usnadníte tím kompatibilitu dat při jejich sdílení. A na to je RDF navrženo — na výměnu dat! Pokud však slovník neexistuje, můžete si jej vytvořit. K tomu je právě RDF Schema nebo expresivnější OWL (OWL 2 Web Ontology Language). My jsme slovník pro data o akademických projektech našli, ale nevyhovoval nám 100%. Proto jsme si napsali malé rozšíření. Obojí si podrobně popíšeme.
Pro další popis projektů potřebujeme následující slovníky: samotné RDF, FOAF pro popis lidí, skupin a vztahů a hlavně ARPFO pro popis akademických výzkumných projektů a jejich financování. S jejich pomocí jsme schopní z neurčitého ID/adresy, které jsme v jsme vytvořili, udělat projekt a jeho popis. Jako první uvedeme „datový typ“.
<http://example.com/resource/1> rdf:type arpfo:Project .
Project je termín (třída) definovaný právě ve slovníku ARPFO a označuje akademický projekt. Pro přiřazení typu ke zdroji složí vlastnost type, která je součástí přímo RDF. Jak vidíme, v N3 funguje podobný systém prefixů jako jmenné prostory v XML. Jejich definici jsme pro stručnost vynechali. Znění jednotlivých jmenných prostorů najdete v dokumentaci jednotlivých slovníků. Bez nich by naše trojice byla delší.
<http://example.com/resource/1>
<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>
<http://vocab.ouls.ox.ac.uk/projectfunding#Project> .
Každý zdroj může mít i více typů, dává–li to smysl. V našem případě můžeme využít i jiný termín pro projekt, který nabízí slovník FOAF.
<http://example.com/resource/1> rdf:type arpfo:Project .
<http://example.com/resource/1> rdf:type foaf:Project .
Projektu bychom měli dát také jméno a vlastnost name ze slovníku FOAF je asi tím nejuniverzálnějším, co je k dispozici. foaf:name může mít jakýkoliv typ zdroje.
<http://example.com/resource/1> foaf:name "Vzorový projekt" .
Schéma rozmyšlené máme, jak to naprogramovat?
Konec teorie o datovém modelu, jdeme programovat skripty, kterými data uložíme, načteme a zobrazíme. Uvidíte, že práce s RDF není vůbec obtížná. Programovat budeme v PHP, použijeme RDF framework ARC2 a s daty budeme pracovat pomocí dotazovacího jazyka SPARQL, který byl pro RDF navržen. V
Instalace frameworku ARC2 do webové aplikace se skládá ze tří triviálních kroků:
-
Rozbalení zdrojových kódů a připojení do skriptu.
<?php require_once('path/to/arc/ARC2.php'); ?> -
Konfigurace spojení do databáze a vytvoření objektu
Store(úložiště).<?php $config = array( 'db_host' => 'localhost', 'db_name' => 'databaze', 'db_user' => 'uzivatel', 'db_pwd' => 'heslo', ); $store = ARC2::getStore($config); ?> -
Inicializace tabulek, které ARC2 ke svému běhu potřebuje.
<?php if (!$store->isSetUp()) { $store->setUp(); } ?>
Od této chvíle máme veškeré funkce databáze přístupné přes proměnnou $store. Nejdůležitější určitě jsou metody query(string $dotaz) a getErrors(). Připojení do databáze jsme a nyní vložíme první informace. Necháme uživatele vytvořit nový projekt. Že pracuje s RDF, to mu lze lehce utajit. Pro vstup poslouží jednoduchý webový formulář s jediným polem pro název projektu.
<form action="obsluzny.skript.php" method="POST">
<input type="text" name="t_jmeno" />
<input type="submit" />
</form>
Formulář může vypadat přibližně jako ten níže přiložený, který je součástí webu skupiny KEG, jen trochu stručnější.
Po odeslání na obslužný skript samozřejmě data zkontrolujeme a následně uložíme do databáze. Musíme vytvořit URI zdroje, tedy unikátní identifikátor nově vytvářeného projektu, který ukládáme a pak v dotazu do databáze vyjmenovat všechny trojice, které se o tomto zdroji mají uložit — v tomto případě pouze určení typu a jméno projektu.
<?php
$tJmeno = $_POST['t_jmeno'];
$uri = 'http://example.com/resource/vygenerovany';
$q = "INSERT {
<$uri> rdf:type arpfo:Project .
<$uri> rdf:type foaf:Project .
<$uri> foaf:name \"$tJmeno\" .
}";
$store->query($q);
?>
Takto může uživatel vkládat libovolný akademický projekt, ale jistě by rád viděl jejich seznam. Jak jsme si řekli, SPARQL byl navržen hlavně na dotazování a nyní si pomocí něco načteme seznam všech projektů. V takovém dotaze definujeme seznam proměnných, které chceme do výsledku načíst (nebo přes hvězdičku implicitně vybereme všechny) a pak definujeme vzory trojic, které musí o hledaném zdroji existovat. Pokud existují, je daný zdroj zařazen do výsledku a do proměnných jsou načteny hodnoty.
<?php
$q = 'SELECT ?projekt ?jmeno WHERE {
?projekt rdf:type arpfo:Project .
?projekt rdf:type foaf:Project .
?projekt foaf:name ?jmeno .
}';
$projekty = $store->query($q, 'rows');
if (sizeof($store->getErrors()) > 0) {
echo('Chyba při dotazování');
// A také lze zobrazit všechny chyby z pole,
// které metoda getErrors() vrací
} else {
if (sizeof($projekty) > 0) {
foreach ($projekty as $projekt) {
echo($projekt['jmeno']);
}
} else {
echo('Žádné projekty nejsou dostupné.');
}
}
?>
Výsledný seznam opět neprozradí nic o tom, že pracujeme s RDF grafem, viz druhý přiložený screenshot. Pokud tedy neuvedete identifikátory jednotlivých projektů, jak je na ukázce vidět.
Data umíme uložit a načíst. Stejnými funkcemi je můžeme také modifikovat a mazat. SPARQL zatím nemá dořešenou modifikaci trojic a tak doporučeným postupem je modifikované trojice smazat a uložit znovu. Pro úpravu jména vzorového projektu z úvodu článku budeme tedy volat sled následujících dotazů.
DELETE { <http://example.com/resource/1> foaf:name ?name . }INSERT { <http://example.com/resource/1> foaf:name "Nové jméno" . }
Když slovník není, můžeme ho vytvořit
O tom, že slovník ARPFO není pro danou doménu dostatečný, jsem se již zmiňoval. Konkrétně mi v něm chybí vlastnost pro delší popis projektu. V diskusi, která proběhla, ale ještě bude probíhat jsou možnosti dvě - buď použít obecnou vlastnost dc:description z knihovnického schématu Dublin Core, nebo si vymyslet vlastní termín. Já zvolil možnost vytvořit vlastní vlastnost, která je však odvozena od dc:description a definuje několik dalších omezení, které zpřesňují její použití. Definována je ve slovníku ARPFO Extension. Navržená vlastnost je omezena na zdroje typu arpfo:Project. Tedy, každý zdroj, o kterém existuje tvrzení s vlastností arpfo-extension:description, je typu arpfo:Project, i když o něm takové tvrzení neexistuje. V datovém modelu RDF lze informace odvozovat. Hodnotou vlastnosti může být pouze text (literál).
Vytváření vlastních slovníků nebo jen nových pojmů bychom si měli dobře rozmyslet. Vždy je lepší převzít existující vlastnost, protože je již adoptována jinými aplikacemi a naše data budou pro stroje okamžitě čitelná. Pokud nám však žádný slovník nevyhovuje nebo neexistuje, je na místě vymyslet nový a ten pak dál veřejně propagovat.
Refaktoring schématu a datová integrita
Dvě věci, které se mi na RDF líbí, jsou jednoduchá možnost rozšířit datové schéma a pak, že není třeba řešit integritu dat.
Zatímco v relačních databázích je odkaz na neexistující primární klíč v jiné tabulce nepřípustný, v RDF je to naprosto v pořádku. Zdroj existuje, pokud je o něm v grafu alespoň jedno tvrzení. Dám příklad, kdy je takové chování víc než žádoucí. Mějme osobu, která má e-mail. Jak jsme si napsali úvodu, jakákoliv URI je zdrojem, tedy i tato e-mailová adresa. V grafu může existovat trojice example-osoba:1 foaf:mbox <mailto:one@example.com>, ale zároveň nemusí o e-mailu existovat žádné tvrzení, které by jej dále popisovalo. Podobně to ale může být s adresami elektronických dokumentů, lidmi či čímkoliv jiným.
Na zavedení vlastnosti arpfo-extension:description si ukážeme, jak se v praxi rozšiřuje datové schéma aplikace. Řekneme si, že projekt musí mít jméno povinně a popis mít nemusí. Ve SPARQL dotazech lze nepovinné trojice označit pomocí klíčového slova „volitelný“ (OPTIONAL). Upravíme tedy dotaz, aby načítal také popis projektu, pokud je k dispozici. Pokud bychom nedali trojici pro popis jako volitelnou, žádný projekt by se nenačetl, pokud by popis neměl.
SELECT ?projekt ?jmeno ?popis
WHERE {
?projekt rdf:type arpfo:Project .
?projekt rdf:type foaf:Project .
?projekt foaf:name ?jmeno .
OPTIONAL {
?projekt arpfo-extension:description ?popis .
}
}
ORDER BY ASC(?jmeno)
Sdílení
Pokud svá data budete uchovávat výhradně v interní databázi a veřejně je prezentovat jen ve formě webových stránek, je vlastně jedno, jestli pracujete s relační databází a vámi navržených databázových schématem nebo interně dotazujete nějaký RDF graf. RDF bylo navrženo hlavně na sdílení dat a jejich porozumění stroji. Sjednocuje nejen syntaxi, ale i datový model. Formátů máte v nabídce několik — z těch standarty propagovaných uveďme hlavně RDF/XML na bázi tohoto značkovacího jazyka. Datovým modelem pak jsou jednotlivé slovníky, které používáte pro ukládání svých dat. Budete–li chtít poskytnout vaše data v surové podobě RDF metadat, nejjednodušší je nabídnout nějaký export právě v XML serializaci. I toho lze celkem jednoduše dosáhnout pomocí SPARQL dotazu, jen budete potřebovat nějaký Serializer, který získané trojice převede výsledného formátu pro stažení. Z jazyka SPARQL využijeme další druh dotazu, kterým je DESCRIBE. Ten vrátí všechna tvrzení o všech zdrojích, které vyhoví podmínce v bloku WHERE. V našem případě chceme všechny trojice o všech zdrojích, které jsou typu arpfo:Project.
<?php
// Konfigurace a vytvoření serializeru; nastavíme prefixy
// jmenných prostorů. Ty se objeví ve výsledném XML.
$config = array(
'ns' => array(
'rdf' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
…
)
);
$serRdfXml = ARC2::getRDFXMLSerializer($config);
// Dotážeme se na data z databáze
$q = 'DESCRIBE ?projekt WHERE {
?projekt rdf:type arpfo:Project .
}';
$data = $store->query($q);
// Získané trojice serializujeme do řetězce
$xmlKod =
$serRdfXml->getSerializedIndex($data['result']);
// Odešleme zpět uživateli se správným MIME typem
header('Content-type: application/rdf+xml');
echo($xmlKod);
?>
Pokud je způsob, jak data zpřístupnit, mělo by je také jít přečíst a uložit. Jsme–li v pozici toho, kdo naopak chce načítat data o cizích projektech, máme s knihovnou ARC2 šanci. Existují hned dva přístupy, jak data načíst. První využívá přímo parser tohoto API, který je schopen přečíst lokální i na webu umístěný soubor s daty, rozpoznat správný formát RDF dat a v něm uložené RDF trojice přečíst Ty pak lze uložit do databáze. Druhý způsob využívá SPARQL a vlastně dělá totéž — zvolený lokální/vzdálený zdroj načte do paměti a data uloží do databáze. S čím se zde můžeme setkat poprvé je možnost RDF graf pojmenovat; jak jinak než pomocí URI identifikátoru. Pojmenované grafy mají jednu výhodu pro takovou aplikaci. Pokud ukládáte data z mnoha zdrojů, můžete si je roztřídit podle původu, tj. URI zdroje, odkud data čtete se stane jménem grafu. V prvním případě uvedení jména grafu podporuje přímo třída Store, v druhém případě musíme využít proprietárního rozšíření jazyka SPARQL+, které knihovna nabízí. V jedné databázi samozřejmě může být více grafů.
<?php
// Načtení pomocí RDF parseru
$parser = ARC2::getRDFParser();
$parser->parse('http://other.example.com/project.rdf');
$triples = $parser->getTriples();
$store->insert($triples, 'http://example.com/');
// Načtení pomocí SPARQL
$store->query('LOAD <http://other.example.com/project.rdf>');
if (sizeof($store->getErrors()) > 0) {
// Vypíšeme chybová hlášení
}
// Načtení pomocí SPARQL+ s určením jména cílového grafu
$store->query('LOAD <http://other.example.com/project.rdf> INTO <http://example.com/>');
?>
Další inspirace
V současnosti pomocí RDF metadat a knihovny ARC2 programuji nejen web výzkumné skupiny KEG, ale třeba také prezentaci skupiny Alpengenerator. Každý dílčí úkol přináší nové problémy — hledání, popř. vyvíjený chybějících slovníků, způsob ukládání vícejazyčného obsahu v RDF, ukládání HTML obsahu… O některých problémech si v budoucnu napíšeme více. Stejně tak můžeme otestovat práci s rozšířením Graphite, které je objektovou nadstavbou nad ARC2. Co se prezentace dat týká, můžeme uvažovat o poskytování informací formou tzv. Linked Data a nebo obohatit naše stránky o RDFa značkování. Pokud mohu shrnout mé čerstvé zkušenosti s tímto způsobem programování webových aplikací, přijde mi rychlejší a elegantnější, než při použití relačních databází.
Zdroje: kód webu skupiny KEG, dokumentace ARC2
Published at 14:14:46, Saturday, 24.07.10