SPARQLmtovar/doc/WSO/sparqld.pdfSPARQL Lenguaje de consulta para RDF. RDF RDF es un formato para la...

Post on 04-Sep-2020

11 views 0 download

Transcript of SPARQLmtovar/doc/WSO/sparqld.pdfSPARQL Lenguaje de consulta para RDF. RDF RDF es un formato para la...

SPARQL

SPARQL

SPARQL Lenguaje de consulta para RDF.

RDF

RDF es un formato para la representación de datos generales acerca de los recursos.

RDF se basa en un grafo, donde sujeto y objeto nodos están relacionados por arcos de predicado.

RDF se puede escribir en XML, o como tripletas.

RDF-Schema

RDF esquema es un método para definir las estructuras de archivos RDF.

Permite que recursos RDF se agrupan en clases, y permite que se especifiquen las descripciones de las subclases, subpropiedad y el dominio /rango.

SPARQL es un lenguaje de consulta para RDF.

Proporciona un formato estándar para escribir consultas que se dirigen a datos RDF y un conjunto de reglas estándar para el procesamiento de las consultas y devolver los resultados.

Qué es SPARQL Pronunciado “sparkle”

Acronimo recursivo para

◦ SPARQL Protocol and RDF Query Language

Un lenguaje de consulta semantica

Un lenguaje de consulta para RDF(S)

W3C (15 de enero 2008) Proporciona un estandar para formatear consultas escritas en datos fuentes RDF

Un conjunto de reglas estandars para procesar consultas

http://www.w3.org/TR/rdf-sparql-query/

◦ Diferentes ligas dados por SPARQL, pero lo más reelevante para este modulo es el link:

◦ http://www.w3.org/TR/sparql11-query/

Declaración RDF

Subject Predicate

author http://www.w3schools.com/RDF

Object

Jan Egil Refsnes

SPARQL busca todos los sub-graphs que empata con el grafo descrito por las tripletas de la consulta.

?subject ?predicate ?object

Ejemplo SPARQL tiene algunas similitudes con QL queries.

Note el uso de espacio de nombres (namespaces) en la consulta.

SELECT ?student

WHERE { ?student b:studies bmod:CS414 }

¿Cuales son los espacios de nombres?

b y bmod

Ejemplo:

SELECT ?title

WHERE

{

<http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title

}

Prefijos y namespace En RDF:

<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cd="http://www.recshop.fake/cd#">

En SPARQL:

PREFIX b: <http://...>

PREFIX bmod:

<http://www2.warwick.ac.uk/fac/sci/dcs/teaching/material/>

La palabra clave PREFIX es una versión de la declaración xmlns:namespace y es similar.

El espacio de nombres xmlns:cd , especifica que elementos con el prefijo cd esta en espacio de nombres."http://www.recshop.fake/cd#".

Prefijos Los prefijos no son opcionales en SPARQL, como en XML.

Trata en: http://www.sparql.org/query.html

PREFIX books: <http://example.org/book/>

PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT $book

WHERE

{$book title $title }

>> esto produce un error.

Contra:

PREFIX books: <http://example.org/book/>

PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT $book

WHERE

{$book dc:title $title }

Prefijos usados Prefix IRI

rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#

rdfs: http://www.w3.org/2000/01/rdf-schema#

xsd: http://www.w3.org/2001/XMLSchema#

fn: http://www.w3.org/2005/xpath-functions#

sfn: http://www.w3.org/ns/sparql#

Los prefijos no son opcionales en SPARQL!

Consultas en línea SPARQL http://www.sparql.org/query.html

http://sparql.org/sparql.html

http://demo.openlinksw.com/sparql

http://librdf.org/query

http://factforge.net/sparql

http://dbpedia.org/sparql

Trata de analizar documentos RDF

Ejemplo: http://athena.ics.forth.gr:9090/RDF/VRP/Examples/tap.rdf

(en http://sparql.org/sparql.html o Protege)

Usando SPARQL para encontrar conceptos

Listando tipos distintos RDF

La siguiente consulta lista los distintos dataset usados en rdf:types

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT DISTINCT ?type

WHERE { ?s rdf:type ?type }

Listando clases OWL

PREFIX owl: <http://www.w3.org/2002/07/owl#>

SELECT ?class

WHERE { ?class a owl:Class }

Esto es equivalente con:

PREFIX owl: <http://www.w3.org/2002/07/owl#>

SELECT ?class

WHERE { ?class rdf:type owl:Class }

Listar todas las clases de nivel superior OWL

Para ver todas las clases OWL, subclases de owl:Thing, correr la siguiente consulta

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

PREFIX owl: <http://www.w3.org/2002/07/owl#>

SELECT * WHERE {?s rdfs:subClassOf owl:Thing }

Listar la raiz y conceptos derivados

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

PREFIX owl: <http://www.w3.org/2002/07/owl#>

SELECT ?class

WHERE { ?class rdfs:subClassOf owl:Thing .

FILTER ( ?class != owl:Thing && ?class != owl:Nothing ) .

OPTIONAL { ?class rdfs:subClassOf ?super .

FILTER ( ?super != owl:Thing && ?super != ?class ) } .

FILTER ( !bound(?super) ) }

Formatos de serialización NOTATION-3 (O N3) , TURTLE , Y N-TRIPLES

Turtle Terse RDF Triple Language

Es el más popular.

SPARQL utiliza este formato.

Es un lenguaje breve o conciso.

La URL que identifica el lenguaje Turtle está dada por: ◦ http://www.w3.org/2008/turtle#turtle

El par XML (nombre de espacio de nombres, nombre local) que identifica el lenguaje Turtle es el siguiente:

◦ http://www.w3.org/2008/turtle#, turtle

El prefijo del espacio sugerido es TTL, y un documento Turtle debe usar TTL como la extensión de archivo.

Turtle Un documento Turtle es una colección de declaraciones o sentencias RDF, y cada declaración tiene un formato que se llama un triple o tripleta:

<subject> <predicate> <object>.

Note que • Cada declaración tiene que terminar con un punto; • El sujeto debe estar representado por un URI; • El predicado debe ser representado por un URI; • El objeto puede ser un URI o una literal; • Un URI debe estar rodeado por <>, que se utilizan para delimitar una URI.

Turtle Una literal dada puede tener un idioma o un tipo de datos URI como su sufijo, pero no se le permite tener ambas cosas.

◦ Si se da un sufijo de idioma, el sufijo se crea con un @ junto con la etiqueta del idioma. Por ejemplo, ◦ "this is in English"@en

◦ Si se da un sufijo de tipo de datos, se utiliza ^^: ◦ "10"ˆˆ<http://www.w3.org/2001/XMLSchema#decimal>

◦ "foo"ˆˆhttp://example.org/mydatatype/sometype

◦ No es necesario que la literal tenga un tipo de datos URI o etiqueta de idioma. Por ejemplo, estas dos literales se permiten: ◦ "10"

◦ "foo“

Ejemplos <http://www.liyangyu.com/foaf.rdf#liyang>

<http://xmlns.com/foaf/0.1/name> "liyang yu".

<http://www.liyangyu.com/foaf.rdf#liyang>

<http://xmlns.com/foaf/0.1/interest>

<http://dbpedia.org/resource/Semantic_Web>.

Turtle Para hacer más corta y más fácil de leer el URI del recurso, utilizamos un prefijo del espacio de nombres.

El formato general para la definición de prefijo del espacio de nombres se da de la siguiente manera:

@prefix pref: <uri>.

Donde pref es el nombre corto para el URI. Por ejemplo:

@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

Ejemplo @prefix foaf: <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

liyang:liyang foaf:name "liyang yu".

liyang:liyang foaf:interest <http://dbpedia.org/resource/Semantic_Web>.

Otra forma de abrevias un espacio de nombres es creando un prefijo predeterminado, que actúa como el espacio de nombres "principal" para un documento Turtle.

Para crear un espacio de nombres predeterminado, usamos la misma forma general, pero sin una cadena pref:

@prefix : <uri>.

Por ejemplo:

@prefix : <http://xmlns.com/foaf/0.1/>.

Ejemplo: @prefix : <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

liyang:liyang :name "liyang yu".

liyang:liyang :interest <http://dbpedia.org/resource/Semantic_Web>.

Note que la directiva @base también se utiliza para permitir la abreviación de URIs.

El punto clave a recordar acerca de @base es la siguiente: cada vez que aparece en un documento, que define el URI base contra el cual se van a resolver todos los URI relativos.

1: <subj0> <pred0> <obj0>.

2: @base <http://liyangyu.com/ns0/>.

3: <subj1> <http://liyangyu.com/ns0/pred1> <obj1>.

4: @base <foo/>.

5: <subj2> <pred2> <obj2>.

6: @predix : <bar#>.

7: :subj3 :pred3 :obj3.

8: @predix : <http://liyangyu.com/ns1/>.

9: :subj4 :pred4 :obj4.

<http://liyangyu.com/data/subj0>

<http://liyangyu.com/data/pred0>

<http://liyangyu.com/data/obj0>.

<http://liyangyu.com/ns0/subj1>

<http://liyangyu.com/ns0/pred1>

<http://liyangyu.com/ns0/obj1>.

@base <http://liyangyu.com/ns0/foo/>.

<http://liyangyu.com/ns0/foo/subj2>

<http://liyangyu.com/ns0/foo/pred2>

<http://liyangyu.com/ns0/foo/obj2>.

@predix : <http://liyangyu.com/ns0/foo/bar#>.

<http://liyangyu.com/ns0/foo/bar#subj3>

<http://liyangyu.com/ns0/foo/bar#pred3>

<http://liyangyu.com/ns0/foo/bar#obj3>. <http://liyangyu.com/ns1/subj4>

<http://liyangyu.com/ns1/pred4>

<http://liyangyu.com/ns1/obj4>.

Ejemplo @base 1: <subj0> <pred0> <obj0>.

2: @base <http://liyangyu.com/ns0/>.

3: <subj1> <http://liyangyu.com/ns0/pred1> <obj1>.

4: @base <foo/>.

5: <subj2> <pred2> <obj2>.

6: @predix : <bar#>.

7: :subj3 :pred3 :obj3.

8: @predix : <http://liyangyu.com/ns1/>.

9: :subj4 :pred4 :obj4.

Token a Token a en Turtle es siempre equivalente al siguiente URI:

http://www.w3.org/1999/02/22-rdf-syntax-ns#type

Por lo tanto,

liyang:liyang rdf:type foaf:Person.

Puede escribirse como sigue:

liyang:liyang a foaf:Person.

Comas y puntos y comas Ambos comas y puntos y comas se pueden utilizar para hacer un documento dado más corto. Más específicamente, si se realizan dos o más sentencias con el mismo sujeto y predicado, podemos combinar las declaraciones y los diferentes objetos separados por uno o más comas

Ejemplo:

@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

liyang:liyang foaf:name "liyang yu".

liyang:liyang foaf:interest <http://dbpedia.org/resource/Semantic_Web>.

liyang:liyang foaf:interest <http://semantic-mediawiki.org/>.

@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

liyang:liyang foaf:name "liyang yu".

liyang:liyang foaf:interest <http://dbpedia.org/resource/Semantic_Web>,

<http://semantic-mediawiki.org>.

Si tenemos los mismos sujetos pero diferentes predicados, pero en más de una declaraciones, podemos usar punto y coma para hacerlos más corto.

@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

liyang:liyang foaf:name "liyang yu" ;

foaf:interest <http://www.foaf-project.org/>,

<http://semantic-mediawiki.org>.

Nodos blancos En Turtle, un nodo en blanco se denota por [] y se puede utilizar como el sujeto o el objeto.

“there exists a person named liyang yu”:

Formato Turtle

@prefix foaf: <http://xmlns.com/foaf/0.1/>.

[] a foaf:Person;

foaf:name "liyang yu" .

<?xml version="1.0"?> <rdf:RDF xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <foaf:Person> <foaf:name>liyang yu</foaf:name> </foaf:Person> </rdf:RDF>

Triples:

_:bnode0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>

<http://xmlns.com/foaf/0.1/Person>.

_:bnode0 <http://xmlns.com/foaf/0.1/name> "liyang yu".

Podemos usar nodos blancos para representar un objeto. Por ejemplo,

“Liyang is a person and he knows another person named Connie”:

Formato Turtle:

@prefix foaf: <http://xmlns.com/foaf/0.1/>.

@prefix liyang: <http://www.liyangyu.com/foaf.rdf#>.

liyang:liyang a foaf:Person;

foaf:knows [

a foaf:Person;

foaf:name "connie"

].

<?xml version="1.0"?>

<rdf:RDF xmlns:foaf="http://xmlns.com/foaf/0.1/"

xmlns:liyang="http://www.liyangyu.com/foaf.rdf#"

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

<foaf:Person

rdf:about="http://www.liyangyu.com/foaf.rdf#liyang">

<foaf:knows>

<foaf:Person>

<foaf:name>connie</foaf:name>

</foaf:Person>

</foaf:knows>

</foaf:Person>

</rdf:RDF>

Tripletas:

<http://www.liyangyu.com/foaf.rdf#liyang>

<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>

<http://xmlns.com/foaf/0.1/Person>.

_:bnode0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>

<http://xmlns.com/foaf/0.1/Person>.

_:bnode0 <http://xmlns.com/foaf/0.1/name> "connie".

<http://www.liyangyu.com/foaf.rdf#liyang>

<http://xmlns.com/foaf/0.1/knows> _:bnode0.

Ejercicio Representar el siguiente grafo en formato Turtle y en RDF (use un convertidor).

Ejercicio

Ejercicio

SPARQL Las relaciones en RDF son representadas como tripletas y se almacenan como hechos.

Ejemplo:

Tell: James Dean played in the movie Giant.

¿Como hacemos preguntas de esto? Aún con una sola tripleta, existen algunas preguntas que podríamos formular:

Ask: What did James Dean play in?

Ask: Who played in Giant?

Ask: What did James Dean do in Giant?

Todas esta preguntas pueden consultarse en SPARQL de una forma muy simple, reemplazando parte del triple con una palabra tipo pregunta, como: Who, What, Where, etc.

SPARQL no distingue entre palabras tipo pregunta, así que podemos elegir palabras que tengan sentido en Ingles.

En SPARQL, las palabras pregunta son escritas como el simbolo ? Al inicio, por ejemplo: ?who, ?where, ?when, etc.

Ask: James Dean played in ?what

Answer: Giant

Ask: ?who played in Giant

Answer: James Dean

Ask: James Dean ?what Giant

Answer: played in

SPARQL QUERY LANGUAGE FOR RDF

La sintaxis es similar al formato Turtle:

Tell: :JamesDean :playedIn :Giant .

Ask: :JamesDean :playedIn ?what .

Answer: :Giant

Ask: ?who :playedIn :Giant .

Answer: :JamesDean

Ask: :JamesDean ?what :Giant .

Answer: :playedIn

Select y Where Una consulta SELECT en SPARQL tiene dos partes: un conjunto de palabras pregunta, y un patrón pregunta. La palabra WHERE indica el patrón de selección, escrito con llaves {}.

Ejemplos de patrones pregunta:

WHERE {:JamesDean :playedIn ?what .}

WHERE {?who :playedIn :Giant .}

WHERE {:JamesDean ?what :Giant .}

La consulta inicia con SELECT y una lista de palabras pregunta (variables).

SELECT ?what WHERE {:JamesDean ?playedIn ?what .}

SELECT ?who WHERE {?who :playedIn :Giant .}

SELECT ?what WHERE {:JamesDean ?what :Giant .}

Clausula Where La cláusula WHERE de una consulta SPARQL puede verse como un patrón de grafo, es decir, un patrón que se compara con el grafo de datos.

Ejemplo:

Ask: SELECT ?what WHERE {:JamesDean :playedIn ?what}

Answer: :Giant, :EastOfEden, :RebelWithoutaCause.

En este caso, el patrón tiene un solo triple, JamesDean como el sujeto,:playedIn en que el predicado, y una palabra pregunta como el objeto. La acción del motor de búsqueda es encontrar todos los empates para el patrón en los datos, y devolver todos los valores en los que la palabra pregunta coinciden.

Ejemplo Who were the directors that James Dean worked with?

Quienes dirigieron las películas que James Dean interpretó.

El patrón del grafo para esta consulta tiene las tripletas:

:JamesDean :playedIn ?what .

?what :directedBy ?who .

Ask:

SELECT ?who

WHERE {:JamesDean :playedIn ?what .

?what :directedBy ?who .}

Answer:

:GeorgeStevens, :EliaKazan, :NicholasRay, :FredGuiol

Ejemplo Ask:

SELECT ?what ?who

WHERE {:JamesDean :playedIn ?what .

?what :directedBy ?who .}

Nombrando palabras pregunta Empiezan con ?, y se escribe: ?palabra

(?what es una movie y ?who es un director

Ask:

SELECT ?movie ?director

WHERE { :JamesDean :playedIn ?movie .

?movie :directedBy ?director .

}

Los patrones de grafo los vemos como una cadena simple: James Dean played in some movie that was directed by someone.

Consulta: Actrices que trabajaron con él.

Ask:

SELECT ?actress ?movie

WHERE {:JamesDean :playedIn ?movie .

?actress :playedIn ?movie .

?actress rdf:type :Woman }

java -cp 'Jena-2.6.4/lib/*' arq.sparql --data=Jena-2.6.4/doc/tutorial/RDF_API/data/vc-db-1.rdf --query=Jena-2.6.4/doc/tutorial/RDQL/vc-q1_b

Ejemplo, Jena Consulta:

<?xml version='1.0' encoding='UTF-8'?>

<rdf:RDF

xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'

xmlns:vCard='http://www.w3.org/2001/vcard-rdf/3.0#'

xmlns:info='http://somewhere/peopleInfo#' >

<rdf:Description rdf:about="http://somewhere/JohnSmith/">

<vCard:FN>John Smith</vCard:FN>

<info:age>25</info:age>

<vCard:N rdf:parseType="Resource">

<vCard:Family>Smith</vCard:Family>

<vCard:Given>John</vCard:Given>

</vCard:N>

</rdf:Description>

<rdf:Description

rdf:about="http://somewhere/RebeccaSmith/">

<vCard:FN>Becky Smith</vCard:FN>

<info:age>23</info:age>

<vCard:N rdf:parseType="Resource">

<vCard:Family>Smith</vCard:Family>

<vCard:Given>Rebecca</vCard:Given>

</vCard:N>

</rdf:Description>

<rdf:Description

rdf:about="http://somewhere/SarahJones/">

<vCard:FN>Sarah Jones</vCard:FN>

<vCard:N rdf:parseType="Resource">

<vCard:Family>Jones</vCard:Family>

<vCard:Given>Sarah</vCard:Given>

</vCard:N>

</rdf:Description>

<rdf:Description

rdf:about="http://somewhere/MattJones/">

<vCard:FN>Matt Jones</vCard:FN>

<vCard:N

vCard:Family="Jones"

vCard:Given="Matthew"/>

</rdf:Description>

</rdf:RDF>

vc-db-2.rdf

Consulta SELECT ?x

WHERE {?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith".}

Jena-2.6.4/doc/tutorial/RDQL$ java -cp '../../../lib/*' arq.sparql --data=vc-db-2.rdf --query=vc-q1_b

------------------------------------------------------

| x |

=================================

| <http://somewhere/JohnSmith/> |

-----------------------------------------------------

Consulta SELECT ?x ?fname

WHERE {?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> ?fname .}

/Jena-2.6.4/doc/tutorial/RDQL$java -cp '../../../lib/*' arq.sparql --data=vc-db-2.rdf --query=vc-q2_b

-------------------------------------------------------------------------------------------

| x | fname |

====================================================

| <http://somewhere/MattJones/> | "Matt Jones" |

| <http://somewhere/SarahJones/> | "Sarah Jones" |

| <http://somewhere/RebeccaSmith/> | "Becky Smith" |

| <http://somewhere/JohnSmith/> | "John Smith" |

-------------------------------------------------------------------------------------------

Ejemplo SELECT ?givenName

WHERE {?y <http://www.w3.org/2001/vcard-rdf/3.0#Family> "Smith".

?y <http://www.w3.org/2001/vcard-rdf/3.0#Given> ?givenName.

}

Jena-2.6.4/doc/tutorial/RDQL$ java -cp '../../../lib/*' arq.sparql --data=vc-db-2.rdf --query=vc-q3_b

-------------

| givenName |

=============

| "Rebecca" |

| "John" |

-------------

Estructura de una consulta SELECT # base directive BASE <URI> # list of prefixes PREFIX pref: <URI> ... # result description SELECT... # graph to search FROM . . . # query pattern WHERE { ... } # query modifiers ORDER BY...

define un URI base contra la cual se

resolverán todos los URI relativos en la

consulta, incluyendo los URI definidos

con palabras clave prefijo.

Especifica cuales

variables asociar, o

elementos datos, debe ser

regresados desde la

consulta

Le dice a SPARQL el

punto final

Contiene los patrones del

grafo que especifican el

resultado deseado Como organizar los

resultados de la

consulta

Ejemplo base <http://danbri.org/foaf.rdf>

prefix foaf: <http://xmlns.com/foaf/0.1/>

select *

from <http://danbri.org/foaf.rdf>

where

{

<#danbri> ?property ?value.

}

Prueba:

http://sparql.org/sparql.html

http://demo.openlinksw.com/sparql

URI relativa

URI absoluta

opcional

Salida http://sparql.org/sparql.html

Ejemplo Find all the people known by Dan Brickley

base <http://danbri.org/foaf.rdf>

prefix foaf: <http://xmlns.com/foaf/0.1/>

select *

from <http://danbri.org/foaf.rdf>

where

{

<#danbri> foaf:knows ?friend.

}

Ejemplo Find all the people known by Brickley, show their names, e-mail addresses, and home page information base <http://danbri.org/foaf.rdf>

prefix foaf: <http://xmlns.com/foaf/0.1/>

select *

from <http://danbri.org/foaf.rdf>

where

{

<#danbri> foaf:knows ?friend.

?friend foaf:name ?name.

?friend foaf:mbox ?email.

?friend foaf:homepage ?homepage.

}

Salida

Ejemplo to find all the picture formats that have been used by Brickley’s friends:

base <http://danbri.org/foaf.rdf> prefix foaf: <http://xmlns.com/foaf/0.1/> prefix dc: <http://purl.org/dc/elements/1.1/> select * from http://danbri.org/foaf.rdf where { <#danbri> foaf:knows ?friend. ?friend foaf:depiction ?picture. ?picture dc:format ?imageFormat. }

Ejemplo base <http://danbri.org/foaf.rdf> prefix foaf: <http://xmlns.com/foaf/0.1/> select * from <http://danbri.org/foaf.rdf> where { <#danbri> foaf:knows ?friend. optional { ?friend foaf:name ?name. } optional { ?friend foaf:mbox ?email. } optional { ?friend foaf:homepage ?homepage. } }

Libros https://www.w3.org/2001/sw/wiki/Books