This presentation outlines a design pattern for linking native XML databases such as BaseX, eXist or MarkLogic with triplestores such as Jena Fuseki (TDB) using RESTful XQuery to provide a set of resolvable URIs for the slices and elements in the XML data and an automated way using XQuery scripts to query the XML data, construct SPARQL update statements, and submit these to the triplestore using SPARQL over HTTP
This was presented at the OKFN Edinburgh meeting on 5 March 2013
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Open data edinburgh-napier-2013-03-05
1. Motorbike & Sidecar
XML DATABASES AND TRIPLESTORES
PETER WINSTANLEY
SCOTTISH GOVERNMENT
peter.winstanley@scotland.gsi.gov.uk
2. XML
2
There is a lot of it already available
It has a structure
People “out there” know how to use it
There is a lot of great functionality in the
XML stack
Dr Peter Winstanley: OKF meeting 5 March 2013
3. Native XML Databases
3
No longer something new and esoteric
Schema-free, so you don‟t need to know
what you are storing before you do so
A bit like a file system
Accessible via several modalities
(Native protocols (xmldb), http REST
and WebDAV)
Dr Peter Winstanley: OKF meeting 5 March 2013
4. XPath & XQuery
4
2 ways of computing over XML
XPath works over paths
(facets/axis)
XQuery works over sequences
Dr Peter Winstanley: OKF meeting 5 March 2013
5. XPath
5
Used for querying:
//xml/indicator[code=„ABC‟]
...and computing:
distinct-values(
//xml/indicator/code
)
Dr Peter Winstanley: OKF meeting 5 March 2013
6. XQuery
6
XQuery example
for $i in doc(„mydoc.xml‟)
where $i//xml/indicator/code = „ABC‟
return <result>{$i}</result>
Dr Peter Winstanley: OKF meeting 5 March 2013
7. RESTXQ
7
XQuery over http
Parameterised (REST) URLs
http://server/indicator/code/ABC
Dr Peter Winstanley: OKF meeting 5 March 2013
8. What about triplestores?
8
Store whatever RDF you give them
So, how about:
http://server/indicator/code/ABC
a qb:Slice;
skos:prefLabel „ABC‟ .
Dr Peter Winstanley: OKF meeting 5 March 2013
9. The Plan
9
H
H T
T T
T P
P
HTTP
See also: http://www.xmltoday.org/content/fuseki-using-jena-
semantic-web-platform-marklogic Kurt Cagle, June 2012
Dr Peter Winstanley: OKF meeting 5 March 2013
11. Demo
11
NXD = BaseX
http://basex.org
Triplestore = Fuseki
http://jena.apache.org/
Data = Scottish Neighborhood Stats
http://www.sns.gov.uk/BulkDownloads
/SNS_FullData_XML_20_2_2013.zip
Dr Peter Winstanley: OKF meeting 5 March 2013
12. General Instructions
12
Fuseki ; vanilla install. Startup – should be available on
localhost:3030
BaseX; install, edit the web.xml to allow rest, webdav and
restxq. Create a database (“SNS_ALL”) and add the SNS
data
Put the restxq *.xqm module into the BaseX restxq
directory
Startup and check availability on localhost:8984
Run the script to load the triplestore (can be done using
XQDT in Eclipse)
Query Fuseki ... select * {?s ?p ?o .}
Dr Peter Winstanley: OKF meeting 5 March 2013
13. XQuery to construct and add RDF
13
xquery version "3.0";
(: XQuery main module to load Fuseki with some RDF derived from the SNS_ALL dataset :)
declare function local:load(){
let $i := distinct-values(collection("SNS_ALL")//code)
let $z := for $x in $i
let $s := concat('prefix skos: <http://www.w3.org/2004/02/skos/core#> ',
'prefix qb: <http://purl.org/linked-data/cube#> ',
'insert data {<http://localhost:8984/restxq/sns/indicator/code/',
$x,
'> a qb:Slice; skos:prefLabel "',
$x,
'" .}'
)
let $request :=
<http:request method="post" http-version="1.0">
<http:body media-type="application/x-www-form-urlencoded">
{
concat("update=",
encode-for-uri($s))
}
</http:body>
</http:request>
let $upd := http:send-request($request, "http://localhost:3030/DatabasePathname/update")
return <ret>
<x>{$x}</x>
<resp>{$upd}</resp>
</ret>
return
<out>
{$z}
</out>
};
local:load()
Dr Peter Winstanley: OKF meeting 5 March 2013
14. RESTXQ counterpart for URI resolution
14
xquery version "3.0";
(:~
a RESTXQ interface to the SNS data
:)
module namespace page = 'http://basex.org/modules/web-page';
declare namespace sns = "urn:sns-scotexec-gov-uk/schemas/indicators/0.1";
declare
%restxq:path("sns/indicator/code/{$code}")
function page:indicator($code as xs:string) {
let $r := collection('SNS_ALL')//indicator[code=$code]
return
<SNS1>{$r}</SNS1>
};
Dr Peter Winstanley: OKF meeting 5 March 2013