Jitao Yang wrote:
Another problem is:
if I add another new book which has no authors to the RDF file like:
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:vcard="http://www.w3.org/2001/vcard-rdf/3.0#">
<rdf:Description rdf:about="http://example.org/BookJava">
<vcard:fullname>Book Java</vcard:fullname>
<dc:author>
<rdf:Description
rdf:about="http://example.org/BookJava/authorA">
<dc:fullname>Bob Smith</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author>
<dc:author>
<rdf:Description
rdf:about="http://example.org/BookJava/authorB">
<dc:fullname>Tom Bush</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author>
</rdf:Description>
<rdf:Description rdf:about="http://example.org/BookCpp">
<vcard:fullname>Book Cpp</vcard:fullname>
<dc:author>
<rdf:Description rdf:about="http://example.org/BookCpp/author2">
<dc:fullname>Mike Luck</dc:fullname>
<dc:country>France</dc:country>
</rdf:Description>
</dc:author>
<dc:author>
<rdf:Description rdf:about="http://example.org/BookCpp/author1">
<dc:fullname>Alice Bird</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author>
<dc:author>
<rdf:Description
rdf:about="http://example.org/BookJava/authorB">
<dc:fullname>kobe Mc</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author>
</rdf:Description>
<rdf:Description rdf:about="http://example.org/BookC">
<vcard:fullname>Book C</vcard:fullname>
</rdf:Description>
</rdf:RDF>
I want to query "the books whose authors are all Italian" or "the books
which have no authors",
so I use SPARQL like:
PREFIX dc:<http://purl.org/dc/elements/1.1/>
PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT DISTINCT ?bookName
WHERE {
?bookURI vcard:fullname ?bookName .
OPTIONAL{
?bookURI dc:author ?author .
?author dc:country ?country .
FILTER(?country = \"Italy\") .
OPTIONAL{
?bookURI dc:author ?author2 .
?author2 dc:country ?country2 .
FILTER(?country2 != \"Italy\")
}
FILTER(bound(?country2))
}
FILTER(!bound(?author))
}
I can get the right answers:
---------------
| bookName |
===============
| "Book C" |
| "Book Java" |
---------------
but, my original idea is FILTER(!bound(?country2)) which means filter
the books which have non-Italian authors,
however if I use FILTER(!bound(?country2)), it will return the opposite
answers:
--------------
| bookName |
==============
| "Book C" |
| "Book Cpp" |
--------------
I can not understand the reasons?
Thank you very much if Lee would like to explain to me,
or the other persons who have time to help me?
Because of the !bound(?author), you're only going to receive books that
don't satisfy your outer optional. Because the outer optional requires
an author, this will include books with no author, as you want.
Books with an author will only satisfy the outer optional if
bound(?country2) is true, which is true only if the book has a
non-Italian author. So you end up excluding those as well, as you want.
That said, I think you've made the query overly complicated. Would this
accomplish what you want?
PREFIX dc:<http://purl.org/dc/elements/1.1/>
PREFIX vcard:<http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT DISTINCT ?bookName
WHERE {
?bookURI vcard:fullname ?bookName .
OPTIONAL{
?bookURI dc:author ?author .
?author dc:country ?country .
FILTER(?country != "Italy") .
}
FILTER(!bound(?author))
}
(This is simply the original query but with the part that required at
least one Italian author removed.)
Lee
Best wishes,
Jitao
On Sat, May 30, 2009 at 21:51, Lee Feigenbaum <[email protected]
<mailto:[email protected]>> wrote:
Jitao Yang wrote:
Dear all,
if there is a RDF like:
<?xml version="1.0" encoding="utf-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<rdf:Description rdf:about="http://example.org/BookJava">
<dc:fullname>Book Java</dc:fullname>
<dc:author>
<rdf:Description
rdf:about="http://example.org/BookJava/authorA">
<dc:fullname>Bob Smith</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author> <dc:author>
<rdf:Description
rdf:about="http://example.org/BookJava/authorB">
<dc:fullname>Tom Bush</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author>
</rdf:Description>
<rdf:Description rdf:about="http://example.org/BookCpp">
<dc:fullname>Book Cpp</dc:fullname>
<dc:author>
<rdf:Description
rdf:about="http://example.org/BookCpp/author1">
<dc:fullname>Alice Bird</dc:fullname>
<dc:country>Italy</dc:country>
</rdf:Description>
</dc:author> <dc:author>
<rdf:Description
rdf:about="http://example.org/BookCpp/author2">
<dc:fullname>Mike Luck</dc:fullname>
<dc:country>France</dc:country>
</rdf:Description>
</dc:author>
</rdf:Description>
</rdf:RDF>
and I query the RDF by:
PREFIX dc:<http://purl.org/dc/elements/1.1/>
SELECT DISTINCT ?bookName
WHERE {
?bookName dc:author ?author .
{?author dc:country ?country . FILTER(?country
= "Italy")}
};
the query results are:
---------------------------------
| bookName |
=================================
| <http://example.org/BookCpp> |
| <http://example.org/BookJava> |
---------------------------------
can anybody tell me how to query out the "book whose authors'
country are all Italy "?
which means the query results should be:
---------------------------------
| bookName |
=================================
| <http://example.org/BookJava> |
---------------------------------
Jitao,
It's not pretty, but you should be able to do it with something like:
PREFIX dc:<http://purl.org/dc/elements/1.1/>
SELECT DISTINCT ?bookName
WHERE {
# first, make sure there's an author from italy
?bookName dc:author ?author .
?author dc:country ?country . FILTER(?country = "Italy") .
# next, "try" to find another author not from italy
OPTIONAL {
?bookName dc:author ?author2 .
?author2 dc:country ?country2 .
FILTER(?country2 != "Italy")
}
# finally, we only want this book if we didn't find any non-Italy
# authors
FILTER(!bound(?country2))
}
(Warning, untested query.)
hope this helps,
Lee
Thank you very much for your help!
Best wishes,
Jitao