Olivier Corby, INRIA, April 2008. See also: Corese
We have introduced an xpath() function that enables to evaluate XPath expressions inside SPARQL queries. This enables to extract additional information from external XML documents of from internal rdf:XMLLiteral data. The xpath() function returns a sequence of datatype values.
xpath(): XML x Path -> seq(datatype value)The filter evaluator is extended to process sequences as in XPath. In the example below, we check whether a class and a property have the same label.
select * where {
graph ?g {
?c rdf:type rdfs:Class
?c rdfs:label ?label
}
filter(xpath(?g, "/rdf:RDF/rdf:Property/rdfs:label" ) = str(?label))
}
It is possible to reference a SPARQL variable in the XPath expression.
select * where {
graph ?g {
?c rdf:type rdfs:Class
?c rdfs:label ?label
}
filter(xpath(?g, "/rdf:RDF/rdf:Property[rdfs:label = $label]" ))
}
It is possible to evaluate an XPath expression on rdf:XMLLiteral data.
select * where {
?any c:xmldata ?xml
filter(datatype(?xml) = rdf:XMLLiteral)
filter(xpath(?xml, "//*[@id = $any]" ))
}
XPath result can be returned as result of the query.
select *
xpath(?xml, "//*[@id = $any]/text()") as ?data
where {
?any c:xmldata ?xml
filter(datatype(?xml) = rdf:XMLLiteral)
filter(xpath(?xml, "//*[@id = $any]" ))
}
XPath result can be reused in another XPath match.
select *
xpath(?xml, "//*[@id = $any]") as ?obj
xpath(?obj, "name/text()") as ?name
xpath(?obj, "refe/text()") as ?refe
where {
?any c:xmldata ?xml
}
Using the same design pattern, we introduce an xslt() function that enables to process a stylesheet on an XML document (Idea: Adil El Ghali). The result of the function call can be processed using xpath.
xslt(): XML x XSL -> XML
select *
xslt(?uri, "style.xsl") as ?doc
xpath(?doc, "//*") as ?res
where {
?x c:author ?uri
}
It is also possible to execute a SPARQL query within XSLT (from function xslt()) with the conventions shown below (Idea & Techno: Fabien Gandon). The result of the query is a DOM tree ready to use in the stylesheet.
sparql(): Query -> XML/DOM Result
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns:server="xalan://fr.inria.acacia.corese.Corese"
extension-element-prefixes="server"
>
<xsl:param name='engine' />
<xsl:variable name='query'>
select * where {?x ?p ?y} limit 1
</xsl:variable>
<xsl:variable name='res' select='server:sparql($engine, $query)' />
</xsl:stylesheet>
The sparql() function enables to evaluate a SPARQL query as a filter inside a query. The result is returned as a sequence of sequences of values (one for each variable).
sparql(): Select Query -> seq(seq(datatype value)) sparql(): Ask Query -> xsd:boolean sparql(): Construct/Describe Query -> rdf:XMLLiteral
The operators are extended to operate on sequences as in XPath, e.g. equality (=) succeeds on a collection if one value of the sequence is equal to the argument.
In the example below, we compute a collection of named graph by an inner query and select the result as ?g. In the query, we compare ?g1 and ?g2 with ?g in such a way to select graphs that are in the collection.
select *
sparql(
"select ?g where { graph ?g {?x c:hasCreated ?doc filter(?x ~ 'olivier' ) }}"
) as ?g
where {
graph ?g1 {?x c:hasCreated ?doc1}
graph ?g2 {?x c:hasCreated ?doc2}
filter(?doc1 != ?doc2)
filter(?g1 = ?g && ?g2 = ?g)
}
We have added syntactic sugar to enable to compute from (named) graphs using such an inner query. The from (named) clause can be a variable computed by the result of an expression as shown below.
select *
sparql(
"select ?g where { graph ?g {?x c:hasCreated ?doc filter(?x ~ 'olivier' ) }}"
) as ?g
from ?g
where {
?x c:hasCreated ?doc1
?x c:hasCreated ?doc2
filter(?doc1 != ?doc2)
}
October 2008
The sql() function enables to evaluate an SQL query as a filter inside a query. The result is returned as a sequence of sequences of values (one for each variable).
prefix db: <jdbc:derby://localhost:1527/>
select *
sql(db:DBTest, 'login', 'passwd',
'SELECT name, dept FROM employee WHERE age > 18') as (?name, ?dept)
where {
?x c:name ?n
filter(?n = ?name)
}