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




Reply via email to