%META:TOPICPARENT{name="VOSIndex"}%
---+ Guide to using SPARQL inside XSLT
This guide demonstrates how Virtuoso allows SPARQL queries to be embedded into
an XSLT style sheet, and executed against a remote SPARQL endpoint (here, we use
the [[http://lod.openlinksw.com/sparql/][LOD Cloud Cache]]) to retrieve data for
use in HTML output.
---++Implementation
* The key component of this feature is the <xsl:for-each-row>
control element. This element has one attribute, named either "sparql"
or "sql"
; the value of the attribute is an XPath expression that
returns the text of the query to executed, e.g.,
* The XPath expression can be a plain string constant, but because the query can
be quite long, it is usually more convenient to store the text in a variable and
refer to that variable.
* The SPARQL query may contain parameters (written in the form ?:name
).
A parameter of this sort will get its value from the XSLT variable $name
.
(If there is any nesting or recursion, the value(s) will come from the innermost
variables.)
* The query execution in turn creates new XSLT variables that exist inside the
body of <xsl:for-each-row>
. Each result column of a query becomes
one XSLT variable.
* The body of <xsl:for-each-row>
is instantiated once for each
row of the query result set, with new values for the variables in each instantiation.
---++Example
1 Execute from iSQL:
SQL> xslt_sheet ('local://friends.xsl',
xtree_doc ('
SELECT DISTINCT ?maxlinkg
?fnick
?ffullname
?ffname
?flname
?fimg
WHERE
{
SERVICE (DEFINE lang:dialect 65535)
{
{ SELECT DISTINCT ?maxlinkg
?fg
?fnick
?ffullname
?ffname (bif:__max_notnull (?flname1, ?flname2)) AS ?flname
?fimg
WHERE
{
{ SELECT (MAX(?linkg)) AS ?maxlinkg
?f
WHERE
{
{ SELECT DISTINCT ?k
WHERE
{ GRAPH ?kg
{
{ ?k foaf:firstName ?:fname
; foaf:familyName ?:lname
}
UNION
{ ?k foaf:firstName ?:fname
; foaf:family_name ?:lname
}
UNION
{ ?k foaf:name ?:fullname }
}
}
}
GRAPH ?linkg { ?k foaf:knows ?f }
} }
GRAPH ?fg
{ ?f a
. OPTIONAL { ?f foaf:firstName ?ffname }
OPTIONAL { ?f foaf:nickname ?fnick }
OPTIONAL { ?f foaf:name ?ffullname }
OPTIONAL { ?f foaf:familyName ?flname1 }
OPTIONAL { ?f foaf:family_name ?flname2 }
OPTIONAL { ?f foaf:img ?fimg }
}
FILTER ( bound ( ?ffullname )
|| ( bound ( ?ffname )
&& ( bound ( ?flname1 )
|| bound ( ?flname2 )
) ) )
}
ORDER BY ?fullname
?ffname
}
}
}
]]>
Simple demo for SPARQL inside XSLT
Known friends of
|
Nick:
(data from )
|
'));
DB.DBA.VHOST_DEFINE
( lpath=>'/friends/',
ppath => '/!friends/',
is_dav => 1,
vsp_user => 'dba',
opts => vector('noinherit', 1)
);
CREATE PROCEDURE WS.WS."/!friends/"
( INOUT path VARCHAR,
INOUT params ANY,
INOUT lines ANY
)
{
http_value (xslt ('local://friends.xsl', xtree_doc (''), params));
}
;
registry_set ('/!friends/', 'no_vsp_recompile')
;
1 Go to [[http://cname/friends/][http://cname/friends/]], where results should look something like this:
%BR%%BR%%BR%%BR%
%BR%%BR%%BR%%BR%