SlideShare a Scribd company logo
NET   2


 Transforming between RDF and
      XML with XSPARQL
           Net2 Tutorial
            Nuno Lopes
           December, 2010
Integration of Heterogeneous Sources




                           1 / 51
Integration of Heterogeneous Sources



                                       SPARQL




                           1 / 51
Integration of Heterogeneous Sources



                                       SPARQL




                           1 / 51
Integration of Heterogeneous Sources

      XSLT/XQuery

                                       SPARQL




                           1 / 51
Integration of Heterogeneous Sources

      XSLT/XQuery
                           Lowering
                                                         SPARQL




                             Lifting

   Transformations between XML and RDF are not easy, mainly
   due to the heterogeneity of RDF/XML serialisations




                               1 / 51
Integration of Heterogeneous Sources

      XSLT/XQuery

                                                         SPARQL




   Transformations between XML and RDF are not easy, mainly
   due to the heterogeneity of RDF/XML serialisations
   Objective: language capable of integrating heterogeneous
   sources for the Semantic Web


                               1 / 51
Why are such transformations needed? (I)

   Standards in Health Care and Life Sciences




                                  2 / 51
Why are such transformations needed? (I)

   Standards in Health Care and Life Sciences




                                  2 / 51
Why are such transformations needed? (I)

   Standards in Health Care and Life Sciences




   Possible solution for the heterogeneous message formats
       Store your data in RDF
       Convert it to the required XML format when necessary


                                  2 / 51
Why are such transformations needed? (II)

   Creating (X)HTML from an RDF backend (under development):
   http://musicpath.org/




                               3 / 51
Why are such transformations needed? (II)

   Creating (X)HTML from an RDF backend (under development):
   http://musicpath.org/




                               3 / 51
Why are such transformations needed? (II)

   Creating (X)HTML from an RDF backend (under development):
   http://musicpath.org/




                               3 / 51
Toy example for the tutorial




                knows                   knows




                        knows




                               4 / 51
Toy example for the tutorial




                knows                   knows




                        knows




                               4 / 51
Why XQuery/XSLT is not enough:

      Different syntaxes and serialisations for the same RDF graph:

      @prefix alice: <alice/> .                      <rdf:RDF xmlns:foaf="...foaf/0.1/">
      @prefix foaf: <...foaf/0.1/> .                   <foaf:Person>
                                                        <foaf:knows>
      _:b1 rdf:type foaf:Person;                          <foaf:Person foaf:name="Bob"/>
           foaf:knows _:b2.                             </foaf:knows>
      _:b2 rdf:type foaf:Person;                       </foaf:Person>
           foaf:name "Bob".                          </rdf:RDF>

                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/"
      <rdf:RDF xmlns:foaf="...foaf/0.1/"                    xmlns:rdf="...rdf-syntax-ns#">
        xmlns:rdf="...rdf-syntax-ns#">                   <rdf:Description rdf:nodeID="x">
        <rdf:Description rdf:nodeID="b1">                  <foaf:knows rdf:nodeID="y"/>
          <rdf:type                                    </rdf:Description>
            rdf:resource=".../Person"/>                <rdf:Description rdf:nodeID="x">
          <foaf:knows rdf:nodeID="b2"/>                  <rdf:type rdf:resource=".../Person"/>
        </rdf:Description>                             </rdf:Description>
        <rdf:Description rdf:nodeID="b2">              <rdf:Description rdf:nodeID="y">
          <rdf:type                                      <foaf:name>Bob</foaf:name>
              rdf:resource=".../Person"/>              </rdf:Description>
          <foaf:name>Bob</foaf:name>                   <rdf:Description rdf:nodeID="y">
        </rdf:Description>                               <rdf:type rdf:resource=".../Person"/>
      </rdf:RDF>                                       </rdf:Description>
                                                     </rdf:RDF>




                                            5 / 51
Why XQuery/XSLT is not enough:

      Different syntaxes and serialisations for the same RDF graph:

      @prefix alice: <alice/> .                      <rdf:RDF xmlns:foaf="...foaf/0.1/">
      @prefix foaf: <...foaf/0.1/> .                   <foaf:Person>
                         rtle                           <foaf:knows>
                      Tu
      _:b1 rdf:type foaf:Person;
           foaf:knows _:b2.
                                                          <foaf:Person foaf:name="Bob"/>
                                                        </foaf:knows>
      _:b2 rdf:type foaf:Person;                       </foaf:Person>
           foaf:name "Bob".                          </rdf:RDF>

                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/"
      <rdf:RDF xmlns:foaf="...foaf/0.1/"                    xmlns:rdf="...rdf-syntax-ns#">
        xmlns:rdf="...rdf-syntax-ns#">                   <rdf:Description rdf:nodeID="x">
        <rdf:Description rdf:nodeID="b1">                  <foaf:knows rdf:nodeID="y"/>
          <rdf:type                                    </rdf:Description>
            rdf:resource=".../Person"/>                <rdf:Description rdf:nodeID="x">
          <foaf:knows rdf:nodeID="b2"/>                  <rdf:type rdf:resource=".../Person"/>
        </rdf:Description>                             </rdf:Description>
        <rdf:Description rdf:nodeID="b2">              <rdf:Description rdf:nodeID="y">
          <rdf:type                                      <foaf:name>Bob</foaf:name>
              rdf:resource=".../Person"/>              </rdf:Description>
          <foaf:name>Bob</foaf:name>                   <rdf:Description rdf:nodeID="y">
        </rdf:Description>                               <rdf:type rdf:resource=".../Person"/>
      </rdf:RDF>                                       </rdf:Description>
                                                     </rdf:RDF>




                                            5 / 51
Why XQuery/XSLT is not enough:

      Different syntaxes and serialisations for the same RDF graph:

      @prefix alice: <alice/> .                      <rdf:RDF xmlns:foaf="...foaf/0.1/">
                     Tri
                         plele
      @prefix foaf: <...foaf/0.1/> .                   <foaf:Person>

                        urt sto e
                                                        <foaf:knows>
      _:b1 rdf:type foaf:Person;r
                      T
           foaf:knows _:b2.
                                                          <foaf:Person foaf:name="Bob"/>
                                                        </foaf:knows>
      _:b2 rdf:type foaf:Person;                       </foaf:Person>
           foaf:name "Bob".                          </rdf:RDF>

                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/"
      <rdf:RDF xmlns:foaf="...foaf/0.1/"                    xmlns:rdf="...rdf-syntax-ns#">
        xmlns:rdf="...rdf-syntax-ns#">                   <rdf:Description rdf:nodeID="x">
        <rdf:Description rdf:nodeID="b1">                  <foaf:knows rdf:nodeID="y"/>
          <rdf:type                                    </rdf:Description>
            rdf:resource=".../Person"/>                <rdf:Description rdf:nodeID="x">
          <foaf:knows rdf:nodeID="b2"/>                  <rdf:type rdf:resource=".../Person"/>
        </rdf:Description>                             </rdf:Description>
        <rdf:Description rdf:nodeID="b2">              <rdf:Description rdf:nodeID="y">
          <rdf:type                                      <foaf:name>Bob</foaf:name>
              rdf:resource=".../Person"/>              </rdf:Description>
          <foaf:name>Bob</foaf:name>                   <rdf:Description rdf:nodeID="y">
        </rdf:Description>                               <rdf:type rdf:resource=".../Person"/>
      </rdf:RDF>                                       </rdf:Description>
                                                     </rdf:RDF>




                                            5 / 51
Why XQuery/XSLT is not enough:

      Different syntaxes and serialisations for the same RDF graph:

      @prefix alice: <alice/> .
                     Tri                                           RD
                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/">
                         plele
      @prefix foaf: <...foaf/0.1/> .                   <foaf:Person>
                                                                       F/
                                                                            XM
                        urt sto e
                                                        <foaf:knows>
      _:b1 rdf:type foaf:Person;r
                      T
           foaf:knows _:b2.
                                                          <foaf:Person foaf:name="Bob"/>
                                                        </foaf:knows>            L
      _:b2 rdf:type foaf:Person;                       </foaf:Person>
           foaf:name "Bob".                          </rdf:RDF>

                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/"
      <rdf:RDF xmlns:foaf="...foaf/0.1/"                    xmlns:rdf="...rdf-syntax-ns#">
        xmlns:rdf="...rdf-syntax-ns#">                   <rdf:Description rdf:nodeID="x">
        <rdf:Description rdf:nodeID="b1">                  <foaf:knows rdf:nodeID="y"/>
          <rdf:type                                    </rdf:Description>
            rdf:resource=".../Person"/>
                  RDF/XML
          <foaf:knows rdf:nodeID="b2"/>                                 X   ML
                                                       <rdf:Description rdf:nodeID="x">
                                                         <rdf:type rdf:resource=".../Person"/>
        </rdf:Description>                                           F/
                                                       </rdf:Description>
        <rdf:Description rdf:nodeID="b2">                        RD
                                                       <rdf:Description rdf:nodeID="y">
          <rdf:type                                      <foaf:name>Bob</foaf:name>
              rdf:resource=".../Person"/>              </rdf:Description>
          <foaf:name>Bob</foaf:name>                   <rdf:Description rdf:nodeID="y">
        </rdf:Description>                               <rdf:type rdf:resource=".../Person"/>
      </rdf:RDF>                                       </rdf:Description>
                                                     </rdf:RDF>




                                            5 / 51
Why XQuery/XSLT is not enough:

      Different syntaxes and serialisations for the same RDF graph:

      @prefix alice: <alice/> .
                     Tri                                           RD
                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/">
                         plele
      @prefix foaf: <...foaf/0.1/> .                   <foaf:Person>
                                                                       F/
                                                                            XM
                        urt sto e
                                                        <foaf:knows>
      _:b1 rdf:type foaf:Person;r
                      T
           foaf:knows _:b2.
                                                          <foaf:Person foaf:name="Bob"/>
                                                        </foaf:knows>            L
      _:b2 rdf:type foaf:Person;                       </foaf:Person>
           foaf:name "Bob".                          </rdf:RDF>

                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/"
      <rdf:RDF xmlns:foaf="...foaf/0.1/"                    xmlns:rdf="...rdf-syntax-ns#">
        xmlns:rdf="...rdf-syntax-ns#">                   <rdf:Description rdf:nodeID="x">
        <rdf:Description rdf:nodeID="b1">                  <foaf:knows rdf:nodeID="y"/>
          <rdf:type                                    </rdf:Description>
            rdf:resource=".../Person"/>
                  RDF/XML
          <foaf:knows rdf:nodeID="b2"/>                                 X   ML
                                                       <rdf:Description rdf:nodeID="x">
                                                         <rdf:type rdf:resource=".../Person"/>
        </rdf:Description>                                           F/
                                                       </rdf:Description>
        <rdf:Description rdf:nodeID="b2">                        RD
                                                       <rdf:Description rdf:nodeID="y">
          <rdf:type                                      <foaf:name>Bob</foaf:name>
            Any transformation needs to take
              rdf:resource=".../Person"/>
          <foaf:name>Bob</foaf:name>
                                                       </rdf:Description>
                                                       <rdf:Description rdf:nodeID="y">
        </rdf:Description>                               <rdf:type rdf:resource=".../Person"/>
            into account the different RDF/XML
      </rdf:RDF>                                       </rdf:Description>
                                                     </rdf:RDF>

            representations
                                            5 / 51
Why XQuery/XSLT is not enough:

      Different syntaxes and serialisations for the same RDF graph:

      @prefix alice: <alice/> .
                     Tri                                           RD
                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/">
                         plele
      @prefix foaf: <...foaf/0.1/> .                   <foaf:Person>
                                                                       F/
                                                                            XM
                        urt sto e
                                                        <foaf:knows>
      _:b1 rdf:type foaf:Person;r
                      T
           foaf:knows _:b2.
                                                          <foaf:Person foaf:name="Bob"/>
                                                        </foaf:knows>            L
      _:b2 rdf:type foaf:Person;                       </foaf:Person>
           foaf:name "Bob".                          </rdf:RDF>

                                                     <rdf:RDF xmlns:foaf="...foaf/0.1/"
      <rdf:RDF xmlns:foaf="...foaf/0.1/"                    xmlns:rdf="...rdf-syntax-ns#">
        xmlns:rdf="...rdf-syntax-ns#">                   <rdf:Description rdf:nodeID="x">
        <rdf:Description rdf:nodeID="b1">                  <foaf:knows rdf:nodeID="y"/>
          <rdf:type                                    </rdf:Description>
            rdf:resource=".../Person"/>
                  RDF/XML
          <foaf:knows rdf:nodeID="b2"/>                                 X   ML
                                                       <rdf:Description rdf:nodeID="x">
                                                         <rdf:type rdf:resource=".../Person"/>
        </rdf:Description>                                           F/
                                                       </rdf:Description>
        <rdf:Description rdf:nodeID="b2">                        RD
                                                       <rdf:Description rdf:nodeID="y">
          <rdf:type                                      <foaf:name>Bob</foaf:name>
              rdf:resource=".../Person"/>              </rdf:Description>
          <foaf:name>Bob</foaf:name>                   <rdf:Description rdf:nodeID="y">
            Or: end up with different transfor-
        </rdf:Description>
      </rdf:RDF>
                                                         <rdf:type rdf:resource=".../Person"/>
                                                       </rdf:Description>
                                                     </rdf:RDF>
            mations for the same RDF data
                                            5 / 51
Why SPARQL is not enough:


         Great for querying RDF! Easy to output Turtle or
         SPARQL XML results format ...

  prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
  prefix foaf: <http://xmlns.com/foaf/0.1/>

  construct { $X foaf:name $FN.}
  from <vCard.rdf>
  where { $X vc:FN $FN .}


                                   ... but




                                     6 / 51
Why SPARQL is not enough:


         Great for querying RDF! Easy to output Turtle or
         SPARQL XML results format ...

  prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
  prefix foaf: <http://xmlns.com/foaf/0.1/>

  construct { $X foaf:name $FN.}
  from <vCard.rdf>
  where { $X vc:FN $FN .}


                                   ... but

               How to produce arbitrary XML???


                                     6 / 51
XSPARQL

          Transformation language
          XML and RDF formats (based on
          XQuery and SPARQL)




                7 / 51
XSPARQL

          Transformation language
          XML and RDF formats (based on
          XQuery and SPARQL)
          Lifting and Lowering in a single
          language




                7 / 51
Outline

   Overview
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
XPath

        XPath is used to locate nodes in XML trees
        An XPath expression is a sequence of steps separated by /.
        Each step evaluates to a sequence of nodes.

   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>

                   Full spec at http://www.w3.org/TR/xpath20/.
              Tutorial at http://www.w3schools.com/xpath/default.asp.


                                       8 / 51
XPath

        XPath is used to locate nodes in XML trees
        An XPath expression is a sequence of steps separated by /.
        Each step evaluates to a sequence of nodes.

   relations.xml
   <relations>                                       relations node
       <person name="Alice">                         is the root ele-
         <knows>Bob</knows>
         <knows>Charles</knows>                      ment
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>

                   Full spec at http://www.w3.org/TR/xpath20/.
              Tutorial at http://www.w3schools.com/xpath/default.asp.


                                       8 / 51
XPath

        XPath is used to locate nodes in XML trees
        An XPath expression is a sequence of steps separated by /.
        Each step evaluates to a sequence of nodes.

   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>                      3 child elements
       </person>
       <person name="Bob">                           person with at-
         <knows>Charles</knows>                      tribute name
       </person>
       <person name="Charles"/>
   </relations>

                   Full spec at http://www.w3.org/TR/xpath20/.
              Tutorial at http://www.w3schools.com/xpath/default.asp.


                                       8 / 51
XPath

        XPath is used to locate nodes in XML trees
        An XPath expression is a sequence of steps separated by /.
        Each step evaluates to a sequence of nodes.

   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
                                                     Each person el-
       </person>                                     ement can have
       <person name="Charles"/>                      knows childs
   </relations>

                   Full spec at http://www.w3.org/TR/xpath20/.
              Tutorial at http://www.w3schools.com/xpath/default.asp.


                                       8 / 51
XPath Steps

   Step examples
    /relations      Selects the root element relations




   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>




                                      9 / 51
XPath Steps

   Step examples
    /relations          Selects the root element relations
    /relations/person   Selects all person elements that are children of relations




   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>




                                          9 / 51
XPath Steps

   Step examples
    /relations          Selects the root element relations
    /relations/person   Selects all person elements that are children of relations
    //knows             Selects all knows elements (in all the document)



   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>




                                          9 / 51
XPath Predicates

   Predicate examples
    /relations/person[3]          Selects the third person child of relations




   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>




                                      10 / 51
XPath Predicates

   Predicate examples
    /relations/person[3]              Selects the third person child of relations
    /relations/person[position()<3]   Selects the first two person children of relations




   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>




                                          10 / 51
XPath Predicates

   Predicate examples
    /relations/person[3]              Selects the third person child of relations
    /relations/person[position()<3]   Selects the first two person children of relations
    //person[@name=’Alice’]           Selects all person elements which the value of the
                                      name attribute is ’Alice’

   relations.xml
   <relations>
       <person name="Alice">
         <knows>Bob</knows>
         <knows>Charles</knows>
       </person>
       <person name="Bob">
         <knows>Charles</knows>
       </person>
       <person name="Charles"/>
   </relations>




                                          10 / 51
XQuery


  XQuery
       Query language for XML (different requirements than XSLT)
            functional language
            typed language
       Superset of XPath
       Overview of the formal semantics (Normalisation rules, Static
       Typing and Dynamic Evaluation)

                  XQuery spec: http://www.w3.org/TR/xquery/.
   XQuery and XPath Formal Semantics: http://www.w3.org/TR/xquery-semantics/.




                                      11 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

           Prolog:   P   declare namespace prefix="namespace-URI "
           Body:     F   for var in XPath-expression
                     L   let var := XPath-expression
                     W   where XPath-expression
                     O   order by XPath-expression
           Head:     R   return XML + nested XQuery

   Query Example: Convert our relations data into RDF/XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
     $nameA in $person/@name
   where $nameA = "Alice"
   return <foaf:Person>{$nameA,
     for $nameB in $person/knows
     let $friend := <foaf:Person name="{$nameB}"/>
     order by $nameB
     return <foaf:knows>{$friend}</foaf:knows>
   }</foaf:Person>


                                    12 / 51
Schematic view on XQuery

            Prolog:   P   declare namespace prefix="namespace-URI "
            Body:     F   for var in XPath-expression
                      L   let var := XPath-expression
                      W   where XPath-expression
                      O   order by XPath-expression
            Head:     R   return XML + nested XQuery




   Query result
   <foaf:Person xmlns:foaf="http://xmlns.com/foaf/0.1/" name="Alice">
      <foaf:knows>
         <foaf:Person name="Bob"/>
      </foaf:knows>
      <foaf:knows>
         <foaf:Person name="Charles"/>
      </foaf:knows>
   </foaf:Person>




                                     12 / 51
Positional variable at

   Query example: add an id attribute to the relations data
   for $person at $pos in doc("relations.xml")//person
   return <person id="{$pos}">
             {$person/@*, $person/*}
          </person>

   $pos refers to the position of $person in the for expression




                                     13 / 51
Positional variable at

   Query example: add an id attribute to the relations data
   for $person at $pos in doc("relations.xml")//person
   return <person id="{$pos}">
             {$person/@*, $person/*}
          </person>

   $pos refers to the position of $person in the for expression
   Query result
   <person id="1" name="Alice">
      <knows>Bob</knows>
      <knows>Charles</knows>
   </person>
   <person id="2" name="Bob">
      <knows>Charles</knows>
   </person>
   <person id="3" name="Charles"/>




                                     13 / 51
XQuery Formal semantics

   Normalisation rules
   Normalisation rules are rewriting rules that translate XQuery into a
   simplified version (XQuery Core).




                                   14 / 51
XQuery Formal semantics

   Normalisation rules
   Normalisation rules are rewriting rules that translate XQuery into a
   simplified version (XQuery Core).

   Rule application
     1   Static Analysis: Apply normalisation rules and static type
         analysis
     2   Dynamic Evaluation Rules: evaluate expressions




                                    14 / 51
XQuery Formal semantics

   Normalisation rules
   Normalisation rules are rewriting rules that translate XQuery into a
   simplified version (XQuery Core).

   Rule application
     1   Static Analysis: Apply normalisation rules and static type
         analysis
     2   Dynamic Evaluation Rules: evaluate expressions

   Environments
         statEnv contains information needed for performing static
                 type analysis. E.g. varType, funcType, . . .




                                    14 / 51
XQuery Formal semantics

   Normalisation rules
   Normalisation rules are rewriting rules that translate XQuery into a
   simplified version (XQuery Core).

   Rule application
     1   Static Analysis: Apply normalisation rules and static type
         analysis
     2   Dynamic Evaluation Rules: evaluate expressions

   Environments
         statEnv contains information needed for performing static
                 type analysis. E.g. varType, funcType, . . .
         dynEnv contains information needed for the evaluation of
                expressions. E.g. varValue, . . .

                                    14 / 51
Semantics - Normalisation rules example



   for Example
   for $i in (1, 2),
       $j in (3, 4)
   return
     <pair>{ ($i,$j) }</pair>




                                15 / 51
Semantics - Normalisation rules example



   for Example
   for $i in (1, 2),
       $j in (3, 4)
   return
     <pair>{ ($i,$j) }</pair>


   for Normalised example
   for $i in (1, 2) return
     for $j in (3, 4) return
         <pair>{ ($i,$j) }</pair>




                                    15 / 51
Semantics - Normalisation rules example



   For Normalisation
                                                        
                       for $VarName 1 in Expr 1 , · · · ,
                         $VarName n in Expr n           
                       ReturnClause                         Expr
                                    ==
               for $VarName 1 in [Expr 1]Expr return
               ···
               for $VarName n in [Expr n]Expr [ReturnClause]Expr
                                                           ]




                                      16 / 51
Semantics - Static typing example



    For Static Type Analysis
                         statEnv Expr 1 : Type 1
           statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2
                       for $Variable in Expr 1
            statEnv
                       return Expr 2 : Type 2 · quantifier(Type 1 )




                                  17 / 51
Semantics - Static typing example

                                                  : means Expr 1 is
                                                  of type Type 1

    For Static Type Analysis
                         statEnv Expr 1 : Type 1
           statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2
                       for $Variable in Expr 1
            statEnv
                       return Expr 2 : Type 2 · quantifier(Type 1 )




                                  17 / 51
Semantics - Static typing example

       + means extend                               : means Expr 1 is
       the environment                              of type Type 1

    For Static Type Analysis
                         statEnv Expr 1 : Type 1
           statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2
                         for $Variable in Expr 1
            statEnv
                         return Expr 2 : Type 2 · quantifier(Type 1 )




                                    17 / 51
Semantics - Static typing example

       + means extend                               : means Expr 1 is
       the environment                              of type Type 1

    For Static Type Analysis
                         statEnv Expr 1 : Type 1
           statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2
                         for $Variable in Expr 1
            statEnv
                         return Expr 2 : Type 2 · quantifier(Type 1 )


                                          quantifier estimates the
                                          number of solutions: *, +
                                          or ?



                                    17 / 51
Semantics - Dynamic evaluation rules


   Simple for example
   for $i in (1, 2) return $i+1




                                  18 / 51
Semantics - Dynamic evaluation rules
                                            For each result in
                                            the expression
   Simple for example
   for $i in (1, 2) return $i+1




                                  18 / 51
Semantics - Dynamic evaluation rules
                                            For each result in
                                            the expression
   Simple for example                       Variable $i is as-
   for $i in (1, 2) return $i+1
                                            signed the corre-
                                            sponding value




                                  18 / 51
Semantics - Dynamic evaluation rules
                                            For each result in
                                            the expression
   Simple for example                       Variable $i is as-
   for $i in (1, 2) return $i+1
                                            signed the corre-
                                            sponding value
                                            Return expresion
                                            is evaluated




                                  18 / 51
Semantics - Dynamic evaluation rules


   Simple for example
   for $i in (1, 2) return $i+1



   For Dynamic Evaluation (Simplified)

                   dynEnv Expr 1 ⇒ Item1 , . . . , Itemn
          dynEnv + varValue(Variable ⇒ Item1 ) Expr 2 ⇒ Value 1
                                  ···
          dynEnv + varValue(Variable ⇒ Itemn ) Expr 2 ⇒ Value n
                           for $Variable in Expr 1
               dynEnv
                           return Expr 2 ⇒ Value 1 , · · · , Value n



                                     18 / 51
Semantics - Dynamic evaluation rules


   Simple for example
   for $i in (1, 2) return $i+1                ⇒ means Expr 1 eval-
                                               uates to the sequence
                                               Item1 , . . . , Itemn
   For Dynamic Evaluation (Simplified)

                   dynEnv Expr 1 ⇒ Item1 , . . . , Itemn
          dynEnv + varValue(Variable ⇒ Item1 ) Expr 2 ⇒ Value 1
                                  ···
          dynEnv + varValue(Variable ⇒ Itemn ) Expr 2 ⇒ Value n
                           for $Variable in Expr 1
               dynEnv
                           return Expr 2 ⇒ Value 1 , · · · , Value n



                                     18 / 51
Semantics - Dynamic evaluation rules


   Simple for example
  For each Itemi2)add Variable
   for $i in (1, , return $i+1               ⇒ means Expr 1 eval-
  ⇒ Itemi to dynEnv and                      uates to the sequence
  evaluate Expr 2                            Item1 , . . . , Itemn
   For Dynamic Evaluation (Simplified)

                   dynEnv Expr 1 ⇒ Item1 , . . . , Itemn
          dynEnv + varValue(Variable ⇒ Item1 ) Expr 2 ⇒ Value 1
                                  ···
          dynEnv + varValue(Variable ⇒ Itemn ) Expr 2 ⇒ Value n
                         for $Variable in Expr 1
              dynEnv
                         return Expr 2 ⇒ Value 1 , · · · , Value n



                                   18 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
SPARQL (in 3 slides)

   SPARQL
      Query language for RDF




             SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/.
                               SPARQL 1.1 Tutorial:
        http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf.



                                     19 / 51
SPARQL (in 3 slides)

   SPARQL
      Query language for RDF
      RDF represents data as triples: Subject, Predicate, Object.
      An RDF Graph is a set of triples.




             SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/.
                               SPARQL 1.1 Tutorial:
        http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf.



                                     19 / 51
SPARQL (in 3 slides)

   SPARQL
      Query language for RDF
      RDF represents data as triples: Subject, Predicate, Object.
      An RDF Graph is a set of triples.
      SPARQL queries RDF data by pattern matching: given a set
      of triple patterns, finds the corresponding triples in the input
      graph




             SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/.
                               SPARQL 1.1 Tutorial:
        http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf.



                                     19 / 51
SPARQL (in 3 slides)

   SPARQL
      Query language for RDF
      RDF represents data as triples: Subject, Predicate, Object.
      An RDF Graph is a set of triples.
      SPARQL queries RDF data by pattern matching: given a set
      of triple patterns, finds the corresponding triples in the input
      graph
      Actually, matched against the scoping graph: a graph
      equivalent to the input graph but does not share any blank
      nodes with it or the query.

             SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/.
                               SPARQL 1.1 Tutorial:
        http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf.



                                     19 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   construct { $X foaf:name $FN.}
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
Schematic view on SPARQL

                 Prolog:   P   prefix prefix: <namespace-URI >
                 Head:     C   construct { template }
                               select variableList
                 Body:     D   from / from named <dataset-URI >
                           W   where { pattern }
                           M   order by expression
                               limit integer > 0
                               offset integer > 0

  Query Example: Convert between different RDF vocabularies
   prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
   prefix foaf: <http://xmlns.com/foaf/0.1/>

   select $X $FN
   from <vCard.ttl>
   where { $X vc:FN $FN .}
   order by $FN
   limit 1 offset 1



                                     20 / 51
SPARQL select solutions

      Solutions for SPARQL select queries are substitutions for
      the variables present in the head (variableList)




                                21 / 51
SPARQL select solutions

       Solutions for SPARQL select queries are substitutions for
       the variables present in the head (variableList)
       Can be represented as XML

  SPARQL XML Results Format (previous query)
  <sparql xmlns="http://www.w3.org/2005/sparql-results#">
    <head>
      <variable name="X"/>
      <variable name="FN"/>
    </head>
    <results>
      <result>
        <binding name="X"><bnode>b0</bnode></binding>
        <binding name="FN"><literal>Nuno Lopes</literal></binding>
      </result>
    </results>
  </sparql>



                                    21 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
XSPARQL




          Transformation language
          Consume and generate XML and RDF




               22 / 51
XSPARQL




          Transformation language
          Consume and generate XML and RDF
          Syntactic extension of XQuery




                22 / 51
XSPARQL




          Transformation language
          Consume and generate XML and RDF
          Syntactic extension of XQuery
          With a formally defined semantics
          (based on the XQuery semantics)




                22 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
XSPARQL: Combining XQuery with SPARQL


             Prolog:   P    declare namespace prefix="namespace-URI "
                            or prefix prefix: <namespace-URI >
             Body:     F    for var in XPath-expression
                       L    let var := XPath-expression
                       W    where XPath-expression
                       O    order by expression                    or
                       F’   for varlist
                       D    from / from named <dataset-URI >
                       W    where {pattern }
                       M    order by expression
                            limit integer > 0
                            offset integer > 0
             Head:     C    construct
                              { template (with nested XSPARQL) }   or
                       R    return XML + nested XSPARQL




                              23 / 51
XSPARQL: Combining XQuery with SPARQL

 prefix         Prolog:   P    declare namespace prefix="namespace-URI "
 declarations                  or prefix prefix: <namespace-URI >
                Body:     F    for var in XPath-expression
                          L    let var := XPath-expression
                          W    where XPath-expression
                          O    order by expression                    or
                          F’   for varlist
                          D    from / from named <dataset-URI >
                          W    where {pattern }
                          M    order by expression
                               limit integer > 0
                               offset integer > 0
                Head:     C    construct
                                 { template (with nested XSPARQL) }   or
                          R    return XML + nested XSPARQL




                                 23 / 51
XSPARQL: Combining XQuery with SPARQL


               Prolog:   P    declare namespace prefix="namespace-URI "
                              or prefix prefix: <namespace-URI >
Data input     Body:     F    for var in XPath-expression
                         L    let var := XPath-expression
(XML or RDF)             W    where XPath-expression
                         O    order by expression                    or
                         F’   for varlist
                         D    from / from named <dataset-URI >
                         W    where {pattern }
                         M    order by expression
                              limit integer > 0
                              offset integer > 0
               Head:     C    construct
                                { template (with nested XSPARQL) }   or
                         R    return XML + nested XSPARQL




                                23 / 51
XSPARQL: Combining XQuery with SPARQL


               Prolog:   P    declare namespace prefix="namespace-URI "
                              or prefix prefix: <namespace-URI >
               Body:     F    for var in XPath-expression
                         L    let var := XPath-expression
                         W    where XPath-expression
                         O    order by expression                    or
                         F’   for varlist
                         D    from / from named <dataset-URI >
                         W    where {pattern }
                         M    order by expression
                              limit integer > 0
                              offset integer > 0

Data output    Head:     C    construct
                                { template (with nested XSPARQL) }   or
(XML or RDF)             R    return XML + nested XSPARQL




                                23 / 51
XSPARQL: Combining XQuery with SPARQL

 XQuery or      Prolog:   P    declare namespace prefix="namespace-URI "
 SPARQL                        or prefix prefix: <namespace-URI >
 prefix         Body:     F    for var in XPath-expression
                          L    let var := XPath-expression
 declarations             W    where XPath-expression
                          O    order by expression                    or
                          F’   for varlist
                          D    from / from named <dataset-URI >
                          W    where {pattern }
                          M    order by expression
                               limit integer > 0
                               offset integer > 0
                Head:     C    construct
                                 { template (with nested XSPARQL) }   or
                          R    return XML + nested XSPARQL




                                 23 / 51
XSPARQL: Combining XQuery with SPARQL


              Prolog:   P    declare namespace prefix="namespace-URI "
                             or prefix prefix: <namespace-URI >
 Any XQuery   Body:     F    for var in XPath-expression
                        L    let var := XPath-expression
 query                  W    where XPath-expression
                        O    order by expression                    or
                        F’   for varlist
                        D    from / from named <dataset-URI >
                        W    where {pattern }
                        M    order by expression
                             limit integer > 0
                             offset integer > 0
              Head:     C    construct
                               { template (with nested XSPARQL) }   or
                        R    return XML + nested XSPARQL




                               23 / 51
XSPARQL: Combining XQuery with SPARQL


               Prolog:   P    declare namespace prefix="namespace-URI "
                              or prefix prefix: <namespace-URI >
               Body:     F    for var in XPath-expression
                         L    let var := XPath-expression
                         W    where XPath-expression
                         O    order by expression                    or
 SPARQLForClause         F’   for varlist
                         D    from / from named <dataset-URI >
 represents a            W    where {pattern }
 SPARQL query            M    order by expression
                              limit integer > 0
                              offset integer > 0
               Head:     C    construct
                                { template (with nested XSPARQL) }   or
                         R    return XML + nested XSPARQL




                                23 / 51
XSPARQL: Combining XQuery with SPARQL


               Prolog:   P    declare namespace prefix="namespace-URI "
                              or prefix prefix: <namespace-URI >
               Body:     F    for var in XPath-expression
                         L    let var := XPath-expression
                         W    where XPath-expression
                         O    order by expression                    or
                         F’   for varlist
                         D    from / from named <dataset-URI >
                         W    where {pattern }
                         M    order by expression
                              limit integer > 0
 construct                    offset integer > 0
 creates RDF   Head:     C    construct
 output                         { template (with nested XSPARQL) }   or
                         R    return XML + nested XSPARQL




                                23 / 51
Query Example - Lifting

   Convert our relations data into RDF
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
       $nameA in $person/@name,
       $nameB in $person/knows
   construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
               [ foaf:name {data($nameB)}; a foaf:Person ]. }




                                    24 / 51
Query Example - Lifting

   Convert our relations data into RDF
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
                                                            XQuery for
   for $person in doc("relations.xml")//person,           data selec-
       $nameA in $person/@name,
       $nameB in $person/knows
                                                          tion
   construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
               [ foaf:name {data($nameB)}; a foaf:Person ]. }




                                    24 / 51
Query Example - Lifting

   Convert our relations data into RDF
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
                                                            construct
   for $person in doc("relations.xml")//person,           clause gen-
       $nameA in $person/@name,                           erates RDF
       $nameB in $person/knows
   construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
               [ foaf:name {data($nameB)}; a foaf:Person ]. }




                                    24 / 51
Query Example - Lifting

   Convert our relations data into RDF
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
       $nameA in $person/@name,
       $nameB in $person/knows
   construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
               [ foaf:name {data($nameB)}; a foaf:Person ]. }




                                    24 / 51
Query Example - Lifting

   Convert our relations data into RDF
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
                                    Nesting produces
   for $person in doc("relations.xml")//person,
       $nameA in $person/@name,      an RDF literal
       $nameB in $person/knows
   construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
               [ foaf:name {data($nameB)}; a foaf:Person ]. }




                                    24 / 51
Query Example - Lifting

   Convert our relations data into RDF
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";

   for $person in doc("relations.xml")//person,
       $nameA in $person/@name,
       $nameB in $person/knows
   construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
               [ foaf:name {data($nameB)}; a foaf:Person ]. }


   Query result
   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   [ foaf:name "Alice"; a foaf:Person; foaf:knows
     [ foaf:name "Bob"; a foaf:Person ] ].
   [ foaf:name "Alice"; a foaf:Person; foaf:knows
     [ foaf:name "Charles"; a foaf:Person ] ].
   [ foaf:name "Bob"; a foaf:Person; foaf:knows
     [ foaf:name "Charles"; a foaf:Person ] ].



                                     24 / 51
Nesting in construct clauses




   Nesting operators
       {Expr} The result of evaluating Expr will be an RDF literal




                                 25 / 51
Nesting in construct clauses




   Nesting operators
       {Expr} The result of evaluating Expr will be an RDF literal
      :{Expr} Same but for RDF blank nodes
     <{Expr}> and IRIs




                                 25 / 51
Query Example - Lifting (II)

   Convert our relations data into RDF
    declare namespace foaf="http://xmlns.com/foaf/0.1/";
    let $persons := doc("relations.xml")//person
    let $ids := data($persons/@name)
    for $p in $persons
      let $id := fn:index-of($ids, $p/@name)
      construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                  { for $k in $p/knows
                    let $kid := fn:index-of($ids, $k)
                    construct { _:b{$id} foaf:knows _:b{$kid} } } }




                                     26 / 51
Query Example - Lifting (II)

   Convert our relations data into RDF
    declare namespace foaf="http://xmlns.com/foaf/0.1/";
    let $persons := doc("relations.xml")//person
    let $ids := data($persons/@name)                  Keep person iden-
    for $p in $persons
      let $id := fn:index-of($ids, $p/@name)          tifiers
      construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                  { for $k in $p/knows
                    let $kid := fn:index-of($ids, $k)
                    construct { _:b{$id} foaf:knows _:b{$kid} } } }




                                    26 / 51
Query Example - Lifting (II)

   Convert our relations data into RDF
    declare namespace foaf="http://xmlns.com/foaf/0.1/";
    let $persons := doc("relations.xml")//person
    let $ids := data($persons/@name)                  For each person
    for $p in $persons
      let $id := fn:index-of($ids, $p/@name)          lookup their id
      construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                  { for $k in $p/knows
                    let $kid := fn:index-of($ids, $k)
                    construct { _:b{$id} foaf:knows _:b{$kid} } } }




                                    26 / 51
Query Example - Lifting (II)

   Convert our relations data into RDF
    declare namespace foaf="http://xmlns.com/foaf/0.1/";
    let $persons := doc("relations.xml")//person
    let $ids := data($persons/@name)                  The same for each
    for $p in $persons
      let $id := fn:index-of($ids, $p/@name)          person then know
      construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                  { for $k in $p/knows
                    let $kid := fn:index-of($ids, $k)
                    construct { _:b{$id} foaf:knows _:b{$kid} } } }




                                    26 / 51
Query Example - Lifting (II)

   Convert our relations data into RDF
    declare namespace foaf="http://xmlns.com/foaf/0.1/";
    let $persons := doc("relations.xml")//person
    let $ids := data($persons/@name)
    for $p in $persons
      let $id := fn:index-of($ids, $p/@name)
      construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                  { for $k in $p/knows
                    let $kid := fn:index-of($ids, $k)
                    construct { _:b{$id} foaf:knows _:b{$kid} } } }


   Query result (reformatted output)
   @prefix foaf: <http://xmlns.com/foaf/0.1/> .

   _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2, _:b3 .
   _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3 .
   _:b3 a foaf:Person; foaf:name "Charles" .



                                     26 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
          { for $FName from <relations.rdf>
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                    27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name                                     XML con-
     return <person name="{$Name}">
          { for $FName from <relations.rdf>             struction
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                   27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }              SPARQL for
     order by $Name                                 query: “Give me
     return <person name="{$Name}">
          { for $FName from <relations.rdf>         persons and their
            where { $Person foaf:knows $Friend .    names”
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                    27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }              SPARQL for
     order by $Name                                 query: “Give me
     return <person name="{$Name}">
          { for $FName from <relations.rdf>         persons and their
              SPARQL variables
            where { $Person foaf:knows $Friend .    names”
              are $-prefixedfoaf:name $Name.
                    $Person
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                    27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name                                     XML con-
     return <person name="{$Name}">
          { for $FName from <relations.rdf>             struction
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                   27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>         SPARQL for
     where { $Person foaf:name $Name }              query: “Give me
     order by $Name
     return <person name="{$Name}">
                                                    the persons each
          { for $FName from <relations.rdf>         one knows”
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                   27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>         SPARQL for
     where { $Person foaf:name $Name }              query: “Give me
     order by $Name
     return <person name="{$Name}">
                                                    the persons each
          { for $FName from <relations.rdf>         one knows”
            where { $Person foaf:knows $Friend .    $Person and
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }     $Name instanti-
            return <knows> { $FName }</knows>}      ated by the outer
          </person>}
   </relations>                                     loop




                                   27 / 51
Query Example - Lowering


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name                                     XML con-
     return <person name="{$Name}">
          { for $FName from <relations.rdf>             struction
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                   27 / 51
Query Example - Lowering result



   Query result
   <relations>
      <person name="Alice">
         <knows>Charles</knows>
         <knows>Bob</knows>
      </person>
      <person name="Bob">
         <knows>Charles</knows>
      </person>
      <person name="Charles"/>
   </relations>




                                  28 / 51
Online Demo

         Online Demo at: http://xsparql.deri.org/demo/




                      Try it for yourself!



                              29 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
XSPARQL Formal Semantics




     Extend the XQuery semantics
     Adding the normalisation, static type and dynamic evaluation
     rules for the new expressions:
         SPARQL for clause
         construct clause




                               30 / 51
Formal semantics types



   Newly defined types
      RDFTerm is the type of SPARQL variables, with the subtypes:
                   uri
                   bnode
                   literal




                                31 / 51
Formal semantics types



   Newly defined types
      RDFTerm is the type of SPARQL variables, with the subtypes:
                   uri
                   bnode
                   literal
     RDFGraph will be the type of construct expressions




                                31 / 51
Formal semantics types



   Newly defined types
      RDFTerm is the type of SPARQL variables, with the subtypes:
                   uri
                   bnode
                   literal
     RDFGraph will be the type of construct expressions
   PatternSolution is a pair (variableName, RDFTerm)
              representing SPARQL variable bindings




                                31 / 51
SPARQL for - Static Type Analysis




              statEnv + varType(Variable 1 ⇒ RDFTerm;
                                ··· ;
                                Variable n ⇒ RDFTerm
                       ) ReturnExpr : Type 2
                   for $Variable 1 · · · $Variable n DatasetClause
         statEnv   where GroupGraphPattern SolutionModifier
                   return ReturnExpr : Type 2 ∗




                                32 / 51
SPARQL for - Static Type Analysis




                statEnv + varType(Variable 1 ⇒ RDFTerm;
       $Variable 1 · · · $Variable n
                                  ··· ;
       are of type RDFTerm        Variable n ⇒ RDFTerm
                         ) ReturnExpr : Type 2
                      for $Variable 1 · · · $Variable n DatasetClause
         statEnv      where GroupGraphPattern SolutionModifier
                      return ReturnExpr : Type 2 ∗




                                       32 / 51
SPARQL for - Static Type Analysis


                                               ∗ comes from
                                               the sequence of
              statEnv + varType(Variable 1 ⇒ RDFTerm; results
                                               SPARQL
                                  ··· ;
                                  Variable n ⇒ RDFTerm
                        )   ReturnExpr : Type 2
                   for $Variable 1 · · · $Variable n DatasetClause
         statEnv   where GroupGraphPattern SolutionModifier
                   return ReturnExpr : Type 2 ∗




                                32 / 51
Example: Simple SPARQL for




  Simple SPARQL for example
   for $s $p $o
   from <foaf.rdf> where { $s $p $o }
   return ($s, $p, $o)




                                    33 / 51
Example: Simple SPARQL for




                                              For each SPARQL
                                              result
  Simple SPARQL for example
   for $s $p $o
   from <foaf.rdf> where { $s $p $o }
   return ($s, $p, $o)




                                    33 / 51
Example: Simple SPARQL for




                                              For each SPARQL
                                              result
  Simple SPARQL for example
                                              Variables are as-
   for $s $p $o
   from <foaf.rdf> where { $s $p $o }         signed values
   return ($s, $p, $o)




                                    33 / 51
Example: Simple SPARQL for




                                              For each SPARQL
                                              result
  Simple SPARQL for example
                                              Variables are as-
   for $s $p $o
   from <foaf.rdf> where { $s $p $o }         signed values
   return ($s, $p, $o)
                                              Return expresion
                                              is evaluated




                                    33 / 51
SPARQL for - Dynamic Evaluation

         dynEnv   fs:sparql(DatasetClause, GroupGraphPattern,
                            SolutionModifier ) ⇒ PS 1 , . . . , PS m
        dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
                            ...;
                            Variable n ⇒ fs:value(PS 1 , Variable n )
                       ) ReturnExpr ⇒ Value 1
                                    .
                                    .
                                    .
        dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
                          ...;
                          Variable n ⇒ fs:value(PS m , Variable n )
                     ) ReturnExpr ⇒ Value m
                     for $Variable 1 · · · $Variable n
        dynEnv       where GroupGraphPattern SolutionModifier
                     return ReturnExpr ⇒ Value 1 , . . . , Value m



                                  34 / 51
SPARQL for - Dynamic Evaluation

              dynEnv  fs:sparql(DatasetClause, GroupGraphPattern,
                                SolutionModifier ) ⇒ PS 1 , . . . , PS m
            dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
                                ...;
 The results of
                                Variable n ⇒ fs:value(PS 1 , Variable n )
 the SPARQL                ) ReturnExpr ⇒ Value 1
 query                                  .
                                        .
                                        .
             dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
                               ...;
                               Variable n ⇒ fs:value(PS m , Variable n )
                          ) ReturnExpr ⇒ Value m
                          for $Variable 1 · · · $Variable n
             dynEnv       where GroupGraphPattern SolutionModifier
                          return ReturnExpr ⇒ Value 1 , . . . , Value m



                                       34 / 51
SPARQL for - Dynamic Evaluation

              dynEnv  fs:sparql(DatasetClause, GroupGraphPattern,
                                SolutionModifier ) ⇒ PS 1 , . . . , PS m
            dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
                                ...;
 The results of
                                Variable n ⇒ fs:value(PS 1 , Variable n )
 the SPARQL                ) ReturnExpr ⇒ Value 1
 query                                  .
                                        .
                                        .
            dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
                              ...;
    fs:sparql evaluates       Variable n ⇒ fs:value(PS m , Variable n )
    a SPARQL query       ) ReturnExpr ⇒ Value m
                          for $Variable 1 · · · $Variable n
             dynEnv       where GroupGraphPattern SolutionModifier
                          return ReturnExpr ⇒ Value 1 , . . . , Value m



                                       34 / 51
SPARQL for - Dynamic Evaluation

              dynEnv  fs:sparql(DatasetClause, GroupGraphPattern,
                                SolutionModifier ) ⇒ PS 1 , . . . , PS m
            dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
                                ...;
                                Variable n ⇒ fs:value(PS 1 , Variable n )
 For each PS               ) ReturnExpr ⇒ Value 1
 add the values                         .
                                        .
                                        .
 of the variables
             dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
 to dynEnv                     ...;
                                  Variable n ⇒ fs:value(PS m , Variable n )
                             )   ReturnExpr ⇒ Value m
                          for $Variable 1 · · · $Variable n
             dynEnv       where GroupGraphPattern SolutionModifier
                          return ReturnExpr ⇒ Value 1 , . . . , Value m



                                       34 / 51
SPARQL for - Dynamic Evaluation

    fs:value selects
               dynEnv fs:sparql(DatasetClause, GroupGraphPattern,
    the value of                SolutionModifier ) ⇒ PS 1 , . . . , PS m
    VariabledynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
             i from
    the PS                      ...;
                                  Variable n ⇒ fs:value(PS 1 , Variable n )
 For each PS              ) ReturnExpr ⇒ Value 1
 add the values                        .
                                       .
                                       .
 of the variables
             dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
 to dynEnv                     ...;
                                  Variable n ⇒ fs:value(PS m , Variable n )
                             )   ReturnExpr ⇒ Value m
                          for $Variable 1 · · · $Variable n
             dynEnv       where GroupGraphPattern SolutionModifier
                          return ReturnExpr ⇒ Value 1 , . . . , Value m



                                       34 / 51
SPARQL for - Dynamic Evaluation

              dynEnv  fs:sparql(DatasetClause, GroupGraphPattern,
                                SolutionModifier ) ⇒ PS 1 , . . . , PS m
            dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
                                ...;
                                Variable n ⇒ fs:value(PS 1 , Variable n )
 For each PS               ) ReturnExpr ⇒ Value 1
 add the values                         .
                                        .
                                        .
 of the variables
             dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
 to dynEnv                     ...;
                                  Variable n ⇒ fs:value(PS m , Variable n )
                             )   ReturnExpr ⇒ Value m
                          for $Variable 1 · · · $Variable n
             dynEnv       where GroupGraphPattern SolutionModifier
                          return ReturnExpr ⇒ Value 1 , . . . , Value m



                                       34 / 51
SPARQL for - Dynamic Evaluation

              dynEnv   fs:sparql(DatasetClause, GroupGraphPattern,
                                 SolutionModifier ) ⇒ PS 1 , . . . , PS m
             dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 );
                                 ...;
                                 Variable n ⇒ fs:value(PS 1 , Variable n )
                            ) ReturnExpr ⇒ Value 1
                                         .
                                         .
                                         .
 The result dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 );
            of
                              ...;
 the expression
                              Variable n ⇒ fs:value(PS m , Variable n )
 is the sequence         ) ReturnExpr ⇒ Value m
 of computed
                      for $Variable 1 · · · $Variable n
 Value s
             dynEnv       where GroupGraphPattern SolutionModifier
                          return ReturnExpr ⇒ Value 1 , . . . , Value m



                                       34 / 51
construct expressions




                   construct ConstructTemplate       Expr
                                ==
      return fs:evalTemplate [ConstructTemplate ]normaliseTemplate




                                  35 / 51
construct expressions



                                      [·]normaliseTemplate ex-
                                        ]
                                       pands any Turtle short-
                   construct ConstructTemplateits argument
                                       cuts in
                                                    Expr
                                  ==
      return fs:evalTemplate [ConstructTemplate ]normaliseTemplate




                                  35 / 51
construct expressions




      fs:evalTemplate vali-
      dates the created triples
                   construct ConstructTemplate       Expr
                                ==
      return fs:evalTemplate [ConstructTemplate ]normaliseTemplate




                                  35 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
Implementation




                 36 / 51
Implementation




      Each XSPARQL query is rewritten into an XQuery




                              36 / 51
Implementation




      Each XSPARQL query is rewritten into an XQuery
      SPARQLForClauses are translated into SPARQL SELECT
      queries and executed using a SPARQL engine




                              36 / 51
Lifting: Rewriting to XQuery



   Convert our relations data into RDF
   declare namespace foaf="http://xmlns.com/foaf/0.1/";
   let $persons := doc("relations.xml")//person
   let $ids := data($persons/@name)
   for $p in $persons
     let $id := fn:index-of($ids, $p/@name)
     construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                 { for $k in $p/knows
                   let $kid := fn:index-of($ids, $k)
                   construct { _:b{$id} foaf:knows _:b{$kid} } } }




                                    37 / 51
Lifting: Rewriting to XQuery



   Convert our relations data into RDF
   declare namespace foaf="http://xmlns.com/foaf/0.1/";
   let $persons := doc("relations.xml")//person
   let $ids := data($persons/@name)
   for $p in $persons
     let $id := fn:index-of($ids, $p/@name)
     construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}.
                 { for $k in $p/knows
                   let $kid := fn:index-of($ids, $k)
                   construct { _:b{$id} foaf:knows _:b{$kid} } } }




                                    37 / 51
Lifting: Rewriting to XQuery
   Convert our relations data into RDF (partial)
        { for $k in $p/knows
          let $kid := fn:index-of($ids, $k)
          construct { _:b{$id} foaf:knows _:b{$kid} } } }


   Rewritten XQuery (and re-rewritten for presentation purposes)
    for $k at $k_pos in $p/knows
    let $kid := fn:index-of( $ids, $k )
    return
      let $_rdf8 := _xsparql:_binding_term( "_:b", $id, "", "" )
      let $_rdf9 := _xsparql:_binding_term( "_:b", $kid, "", "" )
      return _xsparql:_serialize((
        if (_xsparql:_validSubject($_rdf8) and _xsparql:_validObject($_rdf9))
        then
           ($_rdf8, " foaf:knows ", _xsparql:_rdf_term( $_rdf9 ), " .&#xA;")
        else "")
     ) ) )




                                    37 / 51
Lifting: Rewriting to XQuery
   Convert our relations data into RDF (partial)
        { for $k in $p/knows
          let $kid := fn:index-of($ids, $k)
          construct { _:b{$id} foaf:knows _:b{$kid} } } }


   Rewritten XQuery (and re-rewritten for presentation purposes)
     for $k at $k_pos in $p/knows
     let $kid := fn:index-of( $ids, $k )
     return
       let $_rdf8 := _xsparql:_binding_term( "_:b", $id, "", "" )
       let $_rdf9 := _xsparql:_binding_term( "_:b", $kid, "", "" )
       return _xsparql:_serialize((
    Create (_xsparql:_validSubject($_rdf8) and _xsparql:_validObject($_rdf9))
         if variables of
         then
    type RDFTerm " foaf:knows ", _xsparql:_rdf_term( $_rdf9 ), " .&#xA;")
            ($_rdf8, for
    eachelse "")
          constructed
      ) ) )
    term


                                    37 / 51
Lifting: Rewriting to XQuery
   Convert our relations data into RDF (partial)
        { for $k in $p/knows
          let $kid := fn:index-of($ids, $k)
          construct { _:b{$id} foaf:knows _:b{$kid} } } }


   Rewritten XQuery (and re-rewritten for presentation purposes)
                                           If all the variables
    for $k at $k_pos in $p/knows                    represent valid RDF
    let $kid := fn:index-of( $ids, $k )
    return
                                                    terms for the given
      let $_rdf8 := _xsparql:_binding_term( "_:b", position "" )output
                                                    $id, "", we
      let $_rdf9 := _xsparql:_binding_term( "_:b", the triple "" )
                                                    $kid, "",
      return _xsparql:_serialize((
        if (_xsparql:_validSubject($_rdf8) and _xsparql:_validObject($_rdf9))
        then
           ($_rdf8, " foaf:knows ", _xsparql:_rdf_term( $_rdf9 ), " .&#xA;")
        else "")
     ) ) )




                                    37 / 51
Handling blank nodes in CONSTRUCT

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

   for $id in ("a","b","c","d")
   construct { _:Person a foaf:Person }




                                   38 / 51
Handling blank nodes in CONSTRUCT

   Construct foaf:Person
                                             Blank nodes
   prefix foaf: <http://xmlns.com/foaf/0.1/>
                                             should be different
   for $id in ("a","b","c","d")              for each solution
   construct { _:Person a foaf:Person }




                                   38 / 51
Handling blank nodes in CONSTRUCT

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

   for $id in ("a","b","c","d")
   construct { _:Person a foaf:Person }
                                             Append position
                                             variable to the
   XQuery rewriting                          blank node
   for $id at $id_pos in ("a", "b", "c", "d")
   let $_rdf0 := _xsparql:_binding_term(fn:concat("_:Person","_",$id_pos))
   return
     _xsparql:_serialize( (
       if (_xsparql:_validSubject( $_rdf0 )) then
         ($_rdf0, " ", "a", " ", "foaf:Person", " .&#xA;")
       else "") )




                                   38 / 51
Handling blank nodes in CONSTRUCT

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

   for $id in ("a","b","c","d")
   construct { _:Person a foaf:Person }



   Query result
   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   _:Person_1 a foaf:Person .
   _:Person_2 a foaf:Person .
   _:Person_3 a foaf:Person .
   _:Person_4 a foaf:Person .




                                   38 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
          { for $FName from <relations.rdf>
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                    39 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
          { for $FName from <relations.rdf>
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                    39 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML (partial)
    for $Person $Name from <relations.rdf>
    where { $Person foaf:name $Name }
    order by $Name



   Rewriting to XQuery
    let $_aux_results3 := _xsparql:_sparqlQuery(
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>
     SELECT $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name . } order by $Name " )
    for $_aux_result3 at $_aux_result3_pos in $_aux_results3
      let $Person := _xsparql:_resultNode( $_aux_result3, "Person" )
      let $Name := _xsparql:_resultNode( $_aux_result3, "Name" )




                                    40 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML (partial)
    for $Person $Name from <relations.rdf>
    where { $Person foaf:name $Name }
    order by $Name



   Rewriting to XQuery
    let $_aux_results3 := _xsparql:_sparqlQuery(
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>
     SELECT $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name . } order by $Name " )
    for $_aux_result3 at $_aux_result3_pos in $_aux_results3
      let $Person := _xsparql:_resultNode( $_aux_result3, "Person" )
      let $Name := _xsparql:_resultNode( $_aux_result3, "Name" )




                                    40 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML (partial)
    for $Person $Name from <relations.rdf>
    where { $Person foaf:name $Name }
    order by $Name



   Rewriting to XQuery
    let $_aux_results3 := _xsparql:_sparqlQuery(
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>
     SELECT $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name . } order by $Name " )
    for $_aux_result3 at $_aux_result3_pos in $_aux_results3
      let $Person := _xsparql:_resultNode( $_aux_result3, "Person" )
      let $Name := _xsparql:_resultNode( $_aux_result3, "Name" )




                                    40 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML (partial)
    for $Person $Name from <relations.rdf>
    where { $Person foaf:name $Name }
    order by $Name



   Rewriting to XQuery
    let $_aux_results3 := _xsparql:_sparqlQuery(
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>
     SELECT $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name . } order by $Name " )
    for $_aux_result3 at $_aux_result3_pos in $_aux_results3
      let $Person := _xsparql:_resultNode( $_aux_result3, "Person" )
      let $Name := _xsparql:_resultNode( $_aux_result3, "Name" )




                                    40 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML (partial)
    for $Person $Name from <relations.rdf>          sparqlQuery
    where { $Person foaf:name $Name }
    order by $Name
                                                   Implementation:
                                                   HTTP call, Java
                                                   extension
   Rewriting to XQuery
    let $_aux_results3 := _xsparql:_sparqlQuery(
    "PREFIX foaf: <http://xmlns.com/foaf/0.1/>
     SELECT $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name . } order by $Name " )
    for $_aux_result3 at $_aux_result3_pos in $_aux_results3
      let $Person := _xsparql:_resultNode( $_aux_result3, "Person" )
      let $Name := _xsparql:_resultNode( $_aux_result3, "Name" )




                                    40 / 51
Lowering: Rewriting to XQuery


   Convert FOAF RDF data into XML
    declare namespace foaf = "http://xmlns.com/foaf/0.1/";
    <relations>
    { for $Person $Name from <relations.rdf>
      where { $Person foaf:name $Name }
      order by $Name
      return <person name="{$Name}">
           { for $FName from <relations.rdf>
             where { $Person foaf:knows $Friend .
                     $Person foaf:name $Name.
                     $Friend foaf:name $FName. }
             return <knows> { $FName }</knows>}
           </person>}
    </relations>




                                    41 / 51
Lowering: Rewriting to XQuery

   Convert FOAF RDF data into XML (partial)
    for $FName from   <relations.rdf>
    where { $Person   foaf:knows $Friend .
            $Person   foaf:name $Name.
            $Friend   foaf:name $FName. }



   Rewriting to XQuery
    let $_aux_results5 := _xsparql:_sparqlQuery( fn:concat(
      "PREFIX foaf: <http://xmlns.com/foaf/0.1/>
       SELECT $FName from <relations.rdf>
       where { ", $Person, " foaf:knows $Friend . ",
       $Person, " foaf:name ", $Name, " .
       $Friend foaf:name $FName . } " ) )
    for $_aux_result5 at $_aux_result5_pos in $_aux_results5
    let $FName := _xsparql:_resultNode( $_aux_result5, "FName" )



                                      41 / 51
Lowering: Rewriting to XQuery

   Convert FOAF RDF data into XML (partial)
    for $FName from   <relations.rdf>
    where { $Person   foaf:knows $Friend .
            $Person   foaf:name $Name.
            $Friend   foaf:name $FName. }



   Rewriting to XQuery
    let $_aux_results5 := _xsparql:_sparqlQuery( fn:concat(
      "PREFIX foaf: <http://xmlns.com/foaf/0.1/>     $Person and
       SELECT $FName from <relations.rdf>
       where { ", $Person, " foaf:knows $Friend . ", $Name instanti-
       $Person, " foaf:name ", $Name, " .            ated by the outer
       $Friend foaf:name $FName . } " ) )
                                                     loop
    for $_aux_result5 at $_aux_result5_pos in $_aux_results5
    let $FName := _xsparql:_resultNode( $_aux_result5, "FName" )



                                      41 / 51
Lowering: Rewriting to XQuery

   Convert FOAF RDF data into XML (partial)
    for $FName from   <relations.rdf>
    where { $Person   foaf:knows $Friend .
            $Person   foaf:name $Name.
            $Friend   foaf:name $FName. }



   Rewriting to XQuery
    let $_aux_results5 := _xsparql:_sparqlQuery( fn:concat(
      "PREFIX foaf: <http://xmlns.com/foaf/0.1/>     Replaced by their
       SELECT $FName from <relations.rdf>
       where { ", $Person, " foaf:knows $Friend . ", value in the query
       $Person, " foaf:name ", $Name, " .            string
       $Friend foaf:name $FName . } " ) )
    for $_aux_result5 at $_aux_result5_pos in $_aux_results5
    let $FName := _xsparql:_resultNode( $_aux_result5, "FName" )



                                      41 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
Lowering Example


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
          { for $FName from <relations.rdf>
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                    42 / 51
Lowering Example


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
                                                    $Person and
     where { $Person foaf:name $Name }              $Name instanti-
     order by $Name
     return <person name="{$Name}">
                                                    ated by the outer
          { for $FName from <relations.rdf>         loop
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.
                    $Friend foaf:name $FName. }
            return <knows> { $FName }</knows>}
          </person>}
   </relations>




                                   42 / 51
Lowering Example


   Convert FOAF RDF data into XML
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
          { for $FName from <relations.rdf>         If $Person is a
            where { $Person foaf:knows $Friend .
                    $Person foaf:name $Name.        blank node, query
                    $Friend foaf:name $FName. }     joining is done by
            return <knows> { $FName }</knows>}
          </person>}
                                                    the $Name variable
   </relations>




                                   42 / 51
Problem with the Lowering example

   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2.
   _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3.
   _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3.
   _:b3 a foaf:Person; foaf:name "Charles".




                                    43 / 51
Problem with the Lowering example

   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2.
   _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3.
   _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3.
   _:b3 a foaf:Person; foaf:name "Charles".




                                    43 / 51
Problem with the Lowering example

   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2.
   _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3.
   _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3.
   _:b3 a foaf:Person; foaf:name "Charles".


   <relations>
      <person name="Alice">
         <knows>Charles</knows>
         <knows>Bob</knows>
      </person>
      <person name="Alice">
         <knows>Charles</knows>
         <knows>Bob</knows>
      </person>
      <person name="Bob"><knows>Charles</knows></person>
      <person name="Charles"/>
   </relations>



                                    43 / 51
Problem with the Lowering example

   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2.
   _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3.
   _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3.
   _:b3 a foaf:Person; foaf:name "Charles".


   <relations>
      <person name="Alice">
         <knows>Charles</knows>
         <knows>Bob</knows>
      </person>
      <person name="Alice">
         <knows>Charles</knows>
         <knows>Bob</knows>
      </person>
      <person name="Bob"><knows>Charles</knows></person>
      <person name="Charles"/>
   </relations>



                                    43 / 51
Scoped Dataset



   Scoping Graph
   SPARQL query solutions are taken from the scoping graph: a
   graph that is equivalent to the active graph but does not share any
   blank nodes with it or any graph pattern within the query.




                                  44 / 51
Scoped Dataset



   Scoping Graph
   SPARQL query solutions are taken from the scoping graph: a
   graph that is equivalent to the active graph but does not share any
   blank nodes with it or any graph pattern within the query.

   Scoped Dataset
   The XSPARQL scoped dataset allows to make SPARQL queries
   over the previous scoping graph, keeping the same blank node
   assignments




                                  44 / 51
Scoped Dataset Example


   Convert FOAF RDF data into XML (Scoped Dataset)
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
            { for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
            </person>}
   </relations>




                                    45 / 51
Scoped Dataset Example


   Convert FOAF RDF data into XML (Scoped Dataset)
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>         Keep the same
     where { $Person foaf:name $Name }              active dataset
     order by $Name
     return <person name="{$Name}">                 that was last used
            { for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
            </person>}
   </relations>




                                   45 / 51
Scoped Dataset Example


   Convert FOAF RDF data into XML (Scoped Dataset)
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
            { for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
            </person>}
   </relations>




                                    45 / 51
Scoped Dataset Example


   Convert FOAF RDF data into XML (Scoped Dataset)
   declare namespace foaf = "http://xmlns.com/foaf/0.1/";
   <relations>
   { for $Person $Name from <relations.rdf>
     where { $Person foaf:name $Name }
     order by $Name
     return <person name="{$Name}">
            { for $FName                            Can no longer
              where { $Person foaf:knows $Friend . be implemented
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
                                                    as rewriting to a
            </person>}                              SPARQL query
   </relations>




                                   45 / 51
Scoped Dataset Example


   Query output
   <relations>
      <person name="Alice">
         <knows>Charles</knows>
      </person>
      <person name="Alice">
         <knows>Bob</knows>
      </person>
      <person name="Bob">
         <knows>Charles</knows>
      </person>
      <person name="Charles"/>
   </relations>




                                  45 / 51
Scoped Dataset Example


   Query output
   <relations>
      <person name="Alice">
         <knows>Charles</knows>
      </person>
      <person name="Alice">
         <knows>Bob</knows>
      </person>
      <person name="Bob">
         <knows>Charles</knows>
      </person>
      <person name="Charles"/>
   </relations>




                                  45 / 51
Constructed Dataset

       Assign the result of a construct query to a variable
       The variable can then be used as the dataset of a SPARQL
       query
   Lifting and Lowering query :)
   let $ds := for $person in doc("relations.xml")//person,
         $nameA in $person/@name,
         $nameB in $person/knows
     construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
                 [ foaf:name {data($nameB)}; a foaf:Person ]. }
   return <relations>{ for $Person $Name from $ds
     where { $Person foaf:name $Name } order by $Name
     return <person name="{$Name}">{ for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
   </person>}</relations>


                                    46 / 51
Constructed Dataset

       Assign the result of a construct query to a variable
       The variable can then be used as the dataset of a SPARQL
       query
   Lifting and Lowering query :)
   let $ds := for $person in doc("relations.xml")//person,
         $nameA in $person/@name,
         $nameB in $person/knows
     construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
                 [ foaf:name {data($nameB)}; a foaf:Person ]. }
   return <relations>{ for $Person $Name from $ds
     where { $Person foaf:name $Name } order by $Name
     return <person name="{$Name}">{ for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
   </person>}</relations>


                                    46 / 51
Constructed Dataset

       Assign the result of a construct query to a variable
       The variable can then be used as the dataset of a SPARQL
       query
   Lifting and Lowering query :)
   let $ds := for $person in doc("relations.xml")//person,
         $nameA in $person/@name,
         $nameB in $person/knows
     construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
                 [ foaf:name {data($nameB)}; a foaf:Person ]. }
   return <relations>{ for $Person $Name from $ds
     where { $Person foaf:name $Name } order by $Name
     return <person name="{$Name}">{ for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
   </person>}</relations>


                                    46 / 51
Constructed Dataset

       Assign the result of a construct query to a variable
       The variable can then be used as the dataset of a SPARQL
       query
   Lifting and Lowering query :)
   let $ds := for $person in doc("relations.xml")//person,
         $nameA in $person/@name,
         $nameB in $person/knows
     construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
                 [ foaf:name {data($nameB)}; a foaf:Person ]. }
   return <relations>{ forthe
           $ds contains $Person $Name from $ds
           RDF Dataset
     where { $Person foaf:name $Name } order by $Name
     return <person name="{$Name}">{ for $FName
              where { $Person foaf:knows $Friend .
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
   </person>}</relations>


                                    46 / 51
Constructed Dataset

       Assign the result of a construct query to a variable
       The variable can then be used as the dataset of a SPARQL
       query
   Lifting and Lowering query :)
   let $ds := for $person in doc("relations.xml")//person,
         $nameA in $person/@name,
         $nameB in $person/knows
     construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows
                 [ foaf:name {data($nameB)}; a foaf:Person ]. }
   return <relations>{ for $Person $Name from $ds
     where { $Person foaf:name $Name } order by $Name
     return <personLater used in a for $FName
                    name="{$Name}">{
              where { $Person foaf:knows $Friend .
                   from clause
                      $Friend foaf:name $FName. }
              return <knows> { $FName }</knows>}
   </person>}</relations>


                                    46 / 51
Outline

   Overview

   XPath & XQuery
     XPath
     XQuery
     XQuery Semantics

   SPARQL

   XSPARQL
     Syntax
     Semantics
     Implementation
     XSPARQL Features
     Query examples
More expressive SPARQL



   Convert between different RDF vocabularies (SPARQL)
    prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
    prefix foaf: <http://xmlns.com/foaf/0.1/>

    construct { $X foaf:name $FN.}
    from <vCard.ttl>
    where { $X vc:FN $FN .}
    order by $FN
    limit 1 offset 1




                                     47 / 51
More expressive SPARQL




   Convert between different RDF vocabularies
    prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
    prefix foaf: <http://xmlns.com/foaf/0.1/>

    construct { _:b foaf:name {fn:concat($N," ", $F)}.}
    from <vCard.rdf>
    where { $P vc:Given $N. $P vc:Family $F. }




                                    47 / 51
More expressive SPARQL




   Convert between different RDF vocabularies
                                                          Construction
    prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
    prefix foaf: <http://xmlns.com/foaf/0.1/>             of new values
                                                          not available in
    construct { _:b foaf:name {fn:concat($N," ", $F)}.}
    from <vCard.rdf>                                      SPARQL 1.0
    where { $P vc:Given $N. $P vc:Family $F. }




                                    47 / 51
More expressive SPARQL




   Convert between different RDF vocabularies
    prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#>
    prefix foaf: <http://xmlns.com/foaf/0.1/>
                                                          XSPARQL pro-
    construct { _:b foaf:name {fn:concat($N," ", $F)}.}   vides you with
    from <vCard.rdf>
    where { $P vc:Given $N. $P vc:Family $F. }
                                                          all the XQuery
                                                          functions




                                    47 / 51
Query Example - KML Lowering

  Create a KML file from RDF Geolocation data
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>

   <kml xmlns="http://www.opengis.net/kml/2.2">{
    for $person $name $long $lat
    from <http://nunolopes.org/foaf.rdf>
    where { $person a foaf:Person; foaf:name $name;
            foaf:based_near [ a geo:Point; geo:long $long;
                              geo:lat $lat ] }
   return <Placemark>
            <name>{fn:concat("Location of ", $name)}</name>
            <Point>
              <coordinates>{fn:concat($long, ",", $lat, ",0")}
              </coordinates>
            </Point>
          </Placemark>
   }</kml>




                                    48 / 51
Query Example - KML Lowering

  Create a KML file from RDF Geolocation data
   prefix foaf: <http://xmlns.com/foaf/0.1/>       SPARQL:   Per-
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
                                                   sons and their
   <kml xmlns="http://www.opengis.net/kml/2.2">{   geographic lo-
    for $person $name $long $lat
    from <http://nunolopes.org/foaf.rdf>
                                                   cations
    where { $person a foaf:Person; foaf:name $name;
            foaf:based_near [ a geo:Point; geo:long $long;
                              geo:lat $lat ] }
   return <Placemark>
            <name>{fn:concat("Location of ", $name)}</name>
            <Point>
              <coordinates>{fn:concat($long, ",", $lat, ",0")}
              </coordinates>
            </Point>
          </Placemark>
   }</kml>




                                    48 / 51
Query Example - KML Lowering

  Create a KML file from RDF Geolocation data
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>

   <kml xmlns="http://www.opengis.net/kml/2.2">{
    for $person $name $long $lat                    XML repre-
    from <http://nunolopes.org/foaf.rdf>            senting the
    where { $person a foaf:Person; foaf:name $name;
                                                    specific KML
            foaf:based_near [ a geo:Point; geo:long $long;
                              geo:lat $lat ] }      file structure
   return <Placemark>
            <name>{fn:concat("Location of ", $name)}</name>
            <Point>
              <coordinates>{fn:concat($long, ",", $lat, ",0")}
              </coordinates>
            </Point>
          </Placemark>
   }</kml>




                                    48 / 51
Query Example - KML Lowering

  Create a KML file from RDF Geolocation data
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>

   <kml xmlns="http://www.opengis.net/kml/2.2">{
    for $person $name $long $lat
    from <http://nunolopes.org/foaf.rdf>
    where { $person a foaf:Person; foaf:name $name;
            foaf:based_near [ a geo:Point; geo:long $long;
                              geo:lat $lat ] }
   return <Placemark>
            <name>{fn:concat("Location of ", $name)}</name>
            <Point>
              <coordinates>{fn:concat($long, ",", $lat, ",0")}
              </coordinates>
            </Point>
          </Placemark>
   }</kml>




                                    48 / 51
Query Example - KML Lifting

   Create RDF Geolocation data from a KML file
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
   prefix kml: <http://earth.google.com/kml/2.0>

   let $loc := "Departamento de Ingeneria Matematica, U. de Chile"
   for $place in doc(fn:concat("http://maps.google.com/?q=",
                     fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml"))
   let $geo := fn:tokenize($place//kml:coordinates, ",")
   construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]};
                                   geo:lat {$geo[2]} ] }




                                    49 / 51
Query Example - KML Lifting

   Create RDF Geolocation data from a KML file
   prefix foaf: <http://xmlns.com/foaf/0.1/> Google doesn’t know Departa-
                                             mento de Ciencias de la Com-
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
   prefix kml: <http://earth.google.com/kml/2.0>
                                              putacion??
   let $loc := "Departamento de Ingeneria Matematica, U. de Chile"
   for $place in doc(fn:concat("http://maps.google.com/?q=",
                     fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml"))
   let $geo := fn:tokenize($place//kml:coordinates, ",")
   construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]};
                                   geo:lat {$geo[2]} ] }




                                    49 / 51
Query Example - KML Lifting

   Create RDF Geolocation data from a KML file
                                                            Ask Google
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
                                                            Maps for the
   prefix kml: <http://earth.google.com/kml/2.0>            KML descrip-
                                                            tion
   let $loc := "Departamento de Ingeneria Matematica, U. de Chile"
   for $place in doc(fn:concat("http://maps.google.com/?q=",
                     fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml"))
   let $geo := fn:tokenize($place//kml:coordinates, ",")
   construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]};
                                   geo:lat {$geo[2]} ] }




                                    49 / 51
Query Example - KML Lifting

   Create RDF Geolocation data from a KML file
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
   prefix kml: <http://earth.google.com/kml/2.0>
                                                            Construct the
   let $loc := "Departamento de Ingeneria Matematica, U. de Chile"
   for $place in doc(fn:concat("http://maps.google.com/?q=", updated RDF
                                                             graph
                     fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml"))
   let $geo := fn:tokenize($place//kml:coordinates, ",")
   construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]};
                                   geo:lat {$geo[2]} ] }




                                    49 / 51
Query Example - KML Lifting

   Create RDF Geolocation data from a KML file
   prefix foaf: <http://xmlns.com/foaf/0.1/>
   prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
   prefix kml: <http://earth.google.com/kml/2.0>

   let $loc := "Departamento de Ingeneria Matematica, U. de Chile"
   for $place in doc(fn:concat("http://maps.google.com/?q=",
                     fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml"))
   let $geo := fn:tokenize($place//kml:coordinates, ",")
   construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]};
                                   geo:lat {$geo[2]} ] }


   Output RDF data
   @prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> .
   @prefix foaf: <http://xmlns.com/foaf/0.1/> .
   [ foaf:based_near [ a geo:Point ; geo:long "-70.664448" ;
                                     geo:lat "-33.457286" ] ] .



                                     49 / 51
Queries over Linked Data


   Give me all pairs of co-authors and their joint publications.
   let $ds :=
     for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres>
     where { $pub dc:creator [] }
     construct { { for * from $pub where { $p dc:creator $o . }
                  construct { $p dc:creator $o } } }
   let $allauthors := distinct-values(
                          for $o from $ds where {$p dc:creator $o}
                          order by $o return $o)
   for $auth at $auth_pos in $allauthors
    for $coauth in $allauthors[position() > $auth_pos]
       let $commonPubs := count(
        { for $pub from $ds
          where { $pub dc:creator $auth, $coauth }
          return $pub } )
   where ($commonPubs > 0)
   construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] }



                                    50 / 51
Queries over Linked Data


   Give me all pairs of co-authors and their joint publications.
   let $ds :=
     for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres>
     where { $pub dc:creator [] }
     construct { { for * from $pub where { $p dc:creator $o . }
                  construct { $p dc:creator $o } } }
   let $allauthors := distinct-values(                Find all the co-
                          for $o from $ds where {$p dc:creator $o}
                          order by $o return $o)
                                                      authors of Axel
   for $auth at $auth_pos in $allauthors              Polleres
    for $coauth in $allauthors[position() > $auth_pos]
       let $commonPubs := count(
        { for $pub from $ds
          where { $pub dc:creator $auth, $coauth }
          return $pub } )
   where ($commonPubs > 0)
   construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] }



                                    50 / 51
Queries over Linked Data


   Give me all pairs of co-authors and their joint publications.
   let $ds :=
     for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres>
     where { $pub dc:creator [] }                     And the dis-
     construct { { for * from $pub where { $p dc:creator $o . }
                  construct { $p dc:creator $o } } } tinct names
   let $allauthors := distinct-values(
                          for $o from $ds where {$p dc:creator $o}
                          order by $o return $o)
   for $auth at $auth_pos in $allauthors
    for $coauth in $allauthors[position() > $auth_pos]
       let $commonPubs := count(
        { for $pub from $ds
          where { $pub dc:creator $auth, $coauth }
          return $pub } )
   where ($commonPubs > 0)
   construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] }



                                    50 / 51
Queries over Linked Data


   Give me all pairs of co-authors and their joint publications.
   let $ds :=
     for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres>
     where { $pub dc:creator [] }
     construct { { for * from $pub where { $p dc:creator $o . }
                  construct { $p dc:creator $o } } } For each dis-
   let $allauthors := distinct-values(                tinct pair of
                          for $o from $ds where {$p dc:creator $o}
                          order by $o return $o)      authors
   for $auth at $auth_pos in $allauthors
    for $coauth in $allauthors[position() > $auth_pos]
       let $commonPubs := count(
        { for $pub from $ds
          where { $pub dc:creator $auth, $coauth }
          return $pub } )
   where ($commonPubs > 0)
   construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] }



                                    50 / 51
Queries over Linked Data


   Give me all pairs of co-authors and their joint publications.
   let $ds :=
     for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres>
     where { $pub dc:creator [] }
     construct { { for * from $pub where { $p dc:creator $o . }
                  construct { $p dc:creator $o } } }
   let $allauthors := distinct-values(                Count the
                          for $o from $ds where {$p dc:creator $o}
                          order by $o return $o)      number of
   for $auth at $auth_pos in $allauthors              their shared
    for $coauth in $allauthors[position() > $auth_pos]
       let $commonPubs := count(                      publications
        { for $pub from $ds
          where { $pub dc:creator $auth, $coauth }
          return $pub } )
   where ($commonPubs > 0)
   construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] }



                                    50 / 51
Queries over Linked Data


   Give me all pairs of co-authors and their joint publications.
   let $ds :=
     for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres>
     where { $pub dc:creator [] }
     construct { { for * from $pub where { $p dc:creator $o . }
                  construct { $p dc:creator $o } } }
   let $allauthors := distinct-values(
                          for $o from $ds where {$p dc:creator $o}
                          order by $o return $o)
   for $auth at $auth_pos in $allauthors
    for $coauth in $allauthors[position() > $auth_pos]
       let $commonPubs := count(
        { for $pub from $ds                           Create the
          where { $pub dc:creator $auth, $coauth }
          return $pub } )                             RDF output
   where ($commonPubs > 0)
   construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] }



                                    50 / 51
The end...




               http://xsparql.deri.org/
    Downloads: http://sourceforge.net/projects/xsparql/
                            new version coming very soon!
   Mailing List: xsparql-discussion@lists.sourceforge.net
   This tutorial: http://nunolopes.org/presentations/2010.12.17-
                  XSPARQLTutorial.pdf




                                   51 / 51
Outline




   Optimisations
Optimisations & Benchmarks


   Data
      Benchmark suite for XML
          http://www.xml-benchmark.org/
          Provides data generator and 20 benchmark queries
          Data simulates an auction website, containing people, items
          and auctions




                                 52 / 51
Optimisations & Benchmarks


   Data
      Benchmark suite for XML
          http://www.xml-benchmark.org/
          Provides data generator and 20 benchmark queries
          Data simulates an auction website, containing people, items
          and auctions
      Converted XML data to RDF




                                 52 / 51
Optimisations & Benchmarks


   Data
      Benchmark suite for XML
          http://www.xml-benchmark.org/
          Provides data generator and 20 benchmark queries
          Data simulates an auction website, containing people, items
          and auctions
      Converted XML data to RDF
      Queries written using XSPARQL




                                 52 / 51
Optimisations & Benchmarks


   Data
       Benchmark suite for XML
            http://www.xml-benchmark.org/
            Provides data generator and 20 benchmark queries
            Data simulates an auction website, containing people, items
            and auctions
       Converted XML data to RDF
       Queries written using XSPARQL

   Query example
   List the names of persons and the number of items they bought




                                   52 / 51
Benchmark Query example

  XQuery
  let $auction := doc("input.xml") return
  for $p in $auction/site/people/person
  let $a := for $t in $auction/site/closed_auctions/closed_auction
            where $t/buyer/@person = $p/@id
            return $t
  return <item person="{$p/name/text()}">{count($a)}</item>




                                    53 / 51
Benchmark Query example

  XQuery
  let $auction := doc("input.xml") return
  for $p in $auction/site/people/person
  let $a := for $t in $auction/site/closed_auctions/closed_auction
            where $t/buyer/@person = $p/@id
            return $t
  return <item person="{$p/name/text()}">{count($a)}</item>


  Translation to XSPARQL
  for $id $name from <input.rdf>
  where { $person a foaf:Person ; :id $id ; foaf:name $name . }
  return <item person="{$name}">{
    let $x := for * from $rdf
              where { $ca a :ClosedAuction ; :buyer [ :id $id ] . }
              return $ca
    return count($x)
  }</item>



                                    53 / 51
Rewriting to XQuery

   Unoptimised Version
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>
     WHERE { $person a foaf:Person ; :id $id ; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
    return <item person="{$name}">{
    let $x := let $_aux_results2 := _xsparql:_sparqlQuery( fn:concat(
              "SELECT $ca FROM <input.rdf>
               WHERE { $ca a :ClosedAuction ; :buyer [:id ", $id, "] .}"))
      for $_aux_result2 at $_aux_result2_pos in $_aux_results2
      let $ca := _xsparql:_resultNode( $_aux_result2, "ca" )
      return $ca
   return count( $x )
   }</item>




                                    54 / 51
Rewriting to XQuery

   Unoptimised Version
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>
     WHERE { $person a foaf:Person ; :id $id ; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
                                                Outer SPARQL query
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
    return <item person="{$name}">{
    let $x := let $_aux_results2 := _xsparql:_sparqlQuery( fn:concat(
              "SELECT $ca FROM <input.rdf>
               WHERE { $ca a :ClosedAuction ; :buyer [:id ", $id, "] .}"))
      for $_aux_result2 at $_aux_result2_pos in $_aux_results2
      let $ca := _xsparql:_resultNode( $_aux_result2, "ca" )
      return $ca
   return count( $x )
   }</item>




                                    54 / 51
Rewriting to XQuery

   Unoptimised Version
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>
     WHERE { $person a foaf:Person ; :id $id ; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
    return <item person="{$name}">{
                                                Inner SPARQL query
    let $x := let $_aux_results2 := _xsparql:_sparqlQuery( fn:concat(
              "SELECT $ca FROM <input.rdf>
               WHERE { $ca a :ClosedAuction ; :buyer [:id ", $id, "] .}"))
      for $_aux_result2 at $_aux_result2_pos in $_aux_results2
      let $ca := _xsparql:_resultNode( $_aux_result2, "ca" )
      return $ca
   return count( $x )
   }</item>




                                    54 / 51
Rewriting to XQuery

   Optimised Version (nested loop join)
   let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $ca $id from <input.rdf>
     WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") )
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>
     WHERE { $person a foaf:Person; :id $id; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
   return <item person="{$name}">{
    let $x :=
     for $_aux_result4 at $_aux_result4_pos in $_aux_results4
     where $id = _xsparql:_resultNode( $_aux_result4, "id" )
     return _xsparql:_resultNode( $_aux_result4, "ca" )
    return count( $x )
   }</item>




                                    54 / 51
Rewriting to XQuery

   Optimised Version (nested loop join)
   let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $ca $id from <input.rdf>
     WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") )
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>          Inner SPARQL query
     WHERE { $person a foaf:Person; :id $id; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
   return <item person="{$name}">{
    let $x :=
     for $_aux_result4 at $_aux_result4_pos in $_aux_results4
     where $id = _xsparql:_resultNode( $_aux_result4, "id" )
     return _xsparql:_resultNode( $_aux_result4, "ca" )
    return count( $x )
   }</item>




                                  54 / 51
Rewriting to XQuery

   Optimised Version (nested loop join)
   let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $ca $id from <input.rdf>
     WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") )
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>
     WHERE { $person a foaf:Person; :id $id; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
                                                Outer SPARQL query
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
   return <item person="{$name}">{
    let $x :=
     for $_aux_result4 at $_aux_result4_pos in $_aux_results4
     where $id = _xsparql:_resultNode( $_aux_result4, "id" )
     return _xsparql:_resultNode( $_aux_result4, "ca" )
    return count( $x )
   }</item>




                                  54 / 51
Rewriting to XQuery

   Optimised Version (nested loop join)
   let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $ca $id from <input.rdf>
     WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") )
   let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat(
    "SELECT $id $name from <input.rdf>
     WHERE { $person a foaf:Person; :id $id; foaf:name $name .}"))
   for $_aux_result0 at $_aux_result0_pos in $_aux_results0
    let $id := _xsparql:_resultNode( $_aux_result0, "id" )
    let $name := _xsparql:_resultNode( $_aux_result0, "name" )
   return <item person="{$name}">{
    let $x :=
     for $_aux_result4 at $_aux_result4_pos in $_aux_results4
     where $id = _xsparql:_resultNode( $_aux_result4, "id" )
     return _xsparql:_resultNode( $_aux_result4, "ca" )
    return count( $x )
   }</item>




                                    54 / 51
Preliminary results look promising...


                  30000
                                                         XSPARQL
                                                   optimised version
                  25000

                  20000
         Time (sec)




                  15000

                  10000

                      5000

                        0
                             5 10   20           50                    100
                                           Dataset size (MB)
                                    Figure: optimisation query 08




                                                55 / 51

More Related Content

PDF
2011 4IZ440 Semantic Web – RDF, SPARQL, and software APIs
PDF
A Hands On Overview Of The Semantic Web
PDF
Programming with LOD
PPTX
RDF Data Model
PPT
Ontologies in RDF-S/OWL
PPTX
The Semantic Web #10 - SPARQL
PPTX
RDFa Tutorial
PPT
2011 4IZ440 Semantic Web – RDF, SPARQL, and software APIs
A Hands On Overview Of The Semantic Web
Programming with LOD
RDF Data Model
Ontologies in RDF-S/OWL
The Semantic Web #10 - SPARQL
RDFa Tutorial

What's hot (20)

PDF
RDF Tutorial - SPARQL 20091031
PDF
PDF
RDF, SPARQL and Semantic Repositories
PPT
Ist16-04 An introduction to RDF
PPT
Querying the Semantic Web with SPARQL
PPTX
OWL: Yet to arrive on the Web of Data?
PPT
Ks2008 Semanticweb In Action
PPTX
Challenges and applications of RDF shapes
PPTX
Saveface - Save your Facebook content as RDF data
PDF
Two graph data models : RDF and Property Graphs
ODP
Ontologies and Semantic in OpenSource projects
PDF
Mon norton tut_queryinglinkeddata02
PPTX
"RDFa - what, why and how?" by Mike Hewett and Shamod Lacoul
PPTX
ShEx by Example
PDF
RDFa: introduction, comparison with microdata and microformats and how to use it
PDF
An Introduction to RDF and the Web of Data
PPTX
Mapping Relational Databases to Linked Data
PPTX
Introduction to SPARQL
PPTX
Relational Database to RDF (RDB2RDF)
ODP
SPARQL 1.1 Update (2013-03-05)
RDF Tutorial - SPARQL 20091031
RDF, SPARQL and Semantic Repositories
Ist16-04 An introduction to RDF
Querying the Semantic Web with SPARQL
OWL: Yet to arrive on the Web of Data?
Ks2008 Semanticweb In Action
Challenges and applications of RDF shapes
Saveface - Save your Facebook content as RDF data
Two graph data models : RDF and Property Graphs
Ontologies and Semantic in OpenSource projects
Mon norton tut_queryinglinkeddata02
"RDFa - what, why and how?" by Mike Hewett and Shamod Lacoul
ShEx by Example
RDFa: introduction, comparison with microdata and microformats and how to use it
An Introduction to RDF and the Web of Data
Mapping Relational Databases to Linked Data
Introduction to SPARQL
Relational Database to RDF (RDB2RDF)
SPARQL 1.1 Update (2013-03-05)
Ad

Viewers also liked (7)

PDF
Random Manhattan Indexing
PDF
Borders of Decidability in Verification of Data-Centric Dynamic Systems
PDF
Exchanging more than Complete Data
PDF
Extracting Information for Context-aware Meeting Preparation
PDF
Extending DBpedia (LOD) using WikiTables
PDF
Exchanging OWL 2 QL Knowledge Bases
PDF
Federation and Navigation in SPARQL 1.1
Random Manhattan Indexing
Borders of Decidability in Verification of Data-Centric Dynamic Systems
Exchanging more than Complete Data
Extracting Information for Context-aware Meeting Preparation
Extending DBpedia (LOD) using WikiTables
Exchanging OWL 2 QL Knowledge Bases
Federation and Navigation in SPARQL 1.1
Ad

Similar to XSPARQL Tutorial (20)

PPTX
The Semantic Web #5 - RDF (2)
PDF
Tutorial for RDF Graphs
PDF
Semantic Web(Web 3.0) SPARQL
PDF
2016-02 Graphs - PG+RDF
KEY
Linked data: spreading data over the web
PPTX
Infromation Reprentation, Structured Data and Semantics
PPTX
Sparql
PDF
Introduction to RDF
PDF
Introduction to RDFa
PPT
Webofdata
ODP
Semantic Web introduction
PDF
W3C Tutorial on Semantic Web and Linked Data at WWW 2013
PDF
An introduction to Semantic Web and Linked Data
PDF
An introduction to Semantic Web and Linked Data
KEY
How RDFa works
KEY
RDFa Introductory Course Session 2/4 How RDFa
PPTX
Introduction to RDF Data Model
PDF
RDF: what and why plus a SPARQL tutorial
PDF
An introduction to Semantic Web and Linked Data
PPT
SPARQL Query Forms
The Semantic Web #5 - RDF (2)
Tutorial for RDF Graphs
Semantic Web(Web 3.0) SPARQL
2016-02 Graphs - PG+RDF
Linked data: spreading data over the web
Infromation Reprentation, Structured Data and Semantics
Sparql
Introduction to RDF
Introduction to RDFa
Webofdata
Semantic Web introduction
W3C Tutorial on Semantic Web and Linked Data at WWW 2013
An introduction to Semantic Web and Linked Data
An introduction to Semantic Web and Linked Data
How RDFa works
RDFa Introductory Course Session 2/4 How RDFa
Introduction to RDF Data Model
RDF: what and why plus a SPARQL tutorial
An introduction to Semantic Web and Linked Data
SPARQL Query Forms

More from net2-project (10)

PDF
Vector spaces for information extraction - Random Projection Example
PDF
Mining Semi-structured Data: Understanding Web-tables – Building a Taxonomy f...
PDF
Tailoring Temporal Description Logics for Reasoning over Temporal Conceptual ...
PDF
Managing Social Communities
PDF
Data Exchange over RDF
PDF
Exchanging More than Complete Data
PDF
Exchanging More than Complete Data
PDF
Answer-set programming
PDF
Evolving web, evolving search
PPTX
SPARQL1.1 Tutorial, given in UChile by Axel Polleres (DERI)
Vector spaces for information extraction - Random Projection Example
Mining Semi-structured Data: Understanding Web-tables – Building a Taxonomy f...
Tailoring Temporal Description Logics for Reasoning over Temporal Conceptual ...
Managing Social Communities
Data Exchange over RDF
Exchanging More than Complete Data
Exchanging More than Complete Data
Answer-set programming
Evolving web, evolving search
SPARQL1.1 Tutorial, given in UChile by Axel Polleres (DERI)

Recently uploaded (20)

PPTX
Week 4 Term 3 Study Techniques revisited.pptx
PDF
VCE English Exam - Section C Student Revision Booklet
PDF
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
PDF
01-Introduction-to-Information-Management.pdf
PDF
Anesthesia in Laparoscopic Surgery in India
PPTX
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
PDF
Complications of Minimal Access Surgery at WLH
PDF
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
PPTX
Pharma ospi slides which help in ospi learning
PDF
Insiders guide to clinical Medicine.pdf
PPTX
master seminar digital applications in india
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PDF
Basic Mud Logging Guide for educational purpose
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PPTX
Cell Structure & Organelles in detailed.
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PDF
O7-L3 Supply Chain Operations - ICLT Program
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PDF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
PPTX
Cell Types and Its function , kingdom of life
Week 4 Term 3 Study Techniques revisited.pptx
VCE English Exam - Section C Student Revision Booklet
BÀI TẬP BỔ TRỢ 4 KỸ NĂNG TIẾNG ANH 9 GLOBAL SUCCESS - CẢ NĂM - BÁM SÁT FORM Đ...
01-Introduction-to-Information-Management.pdf
Anesthesia in Laparoscopic Surgery in India
The Healthy Child – Unit II | Child Health Nursing I | B.Sc Nursing 5th Semester
Complications of Minimal Access Surgery at WLH
Chapter 2 Heredity, Prenatal Development, and Birth.pdf
Pharma ospi slides which help in ospi learning
Insiders guide to clinical Medicine.pdf
master seminar digital applications in india
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
Basic Mud Logging Guide for educational purpose
STATICS OF THE RIGID BODIES Hibbelers.pdf
Cell Structure & Organelles in detailed.
Module 4: Burden of Disease Tutorial Slides S2 2025
O7-L3 Supply Chain Operations - ICLT Program
Pharmacology of Heart Failure /Pharmacotherapy of CHF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
Cell Types and Its function , kingdom of life

XSPARQL Tutorial

  • 1. NET 2 Transforming between RDF and XML with XSPARQL Net2 Tutorial Nuno Lopes December, 2010
  • 3. Integration of Heterogeneous Sources SPARQL 1 / 51
  • 4. Integration of Heterogeneous Sources SPARQL 1 / 51
  • 5. Integration of Heterogeneous Sources XSLT/XQuery SPARQL 1 / 51
  • 6. Integration of Heterogeneous Sources XSLT/XQuery Lowering SPARQL Lifting Transformations between XML and RDF are not easy, mainly due to the heterogeneity of RDF/XML serialisations 1 / 51
  • 7. Integration of Heterogeneous Sources XSLT/XQuery SPARQL Transformations between XML and RDF are not easy, mainly due to the heterogeneity of RDF/XML serialisations Objective: language capable of integrating heterogeneous sources for the Semantic Web 1 / 51
  • 8. Why are such transformations needed? (I) Standards in Health Care and Life Sciences 2 / 51
  • 9. Why are such transformations needed? (I) Standards in Health Care and Life Sciences 2 / 51
  • 10. Why are such transformations needed? (I) Standards in Health Care and Life Sciences Possible solution for the heterogeneous message formats Store your data in RDF Convert it to the required XML format when necessary 2 / 51
  • 11. Why are such transformations needed? (II) Creating (X)HTML from an RDF backend (under development): http://musicpath.org/ 3 / 51
  • 12. Why are such transformations needed? (II) Creating (X)HTML from an RDF backend (under development): http://musicpath.org/ 3 / 51
  • 13. Why are such transformations needed? (II) Creating (X)HTML from an RDF backend (under development): http://musicpath.org/ 3 / 51
  • 14. Toy example for the tutorial knows knows knows 4 / 51
  • 15. Toy example for the tutorial knows knows knows 4 / 51
  • 16. Why XQuery/XSLT is not enough: Different syntaxes and serialisations for the same RDF graph: @prefix alice: <alice/> . <rdf:RDF xmlns:foaf="...foaf/0.1/"> @prefix foaf: <...foaf/0.1/> . <foaf:Person> <foaf:knows> _:b1 rdf:type foaf:Person; <foaf:Person foaf:name="Bob"/> foaf:knows _:b2. </foaf:knows> _:b2 rdf:type foaf:Person; </foaf:Person> foaf:name "Bob". </rdf:RDF> <rdf:RDF xmlns:foaf="...foaf/0.1/" <rdf:RDF xmlns:foaf="...foaf/0.1/" xmlns:rdf="...rdf-syntax-ns#"> xmlns:rdf="...rdf-syntax-ns#"> <rdf:Description rdf:nodeID="x"> <rdf:Description rdf:nodeID="b1"> <foaf:knows rdf:nodeID="y"/> <rdf:type </rdf:Description> rdf:resource=".../Person"/> <rdf:Description rdf:nodeID="x"> <foaf:knows rdf:nodeID="b2"/> <rdf:type rdf:resource=".../Person"/> </rdf:Description> </rdf:Description> <rdf:Description rdf:nodeID="b2"> <rdf:Description rdf:nodeID="y"> <rdf:type <foaf:name>Bob</foaf:name> rdf:resource=".../Person"/> </rdf:Description> <foaf:name>Bob</foaf:name> <rdf:Description rdf:nodeID="y"> </rdf:Description> <rdf:type rdf:resource=".../Person"/> </rdf:RDF> </rdf:Description> </rdf:RDF> 5 / 51
  • 17. Why XQuery/XSLT is not enough: Different syntaxes and serialisations for the same RDF graph: @prefix alice: <alice/> . <rdf:RDF xmlns:foaf="...foaf/0.1/"> @prefix foaf: <...foaf/0.1/> . <foaf:Person> rtle <foaf:knows> Tu _:b1 rdf:type foaf:Person; foaf:knows _:b2. <foaf:Person foaf:name="Bob"/> </foaf:knows> _:b2 rdf:type foaf:Person; </foaf:Person> foaf:name "Bob". </rdf:RDF> <rdf:RDF xmlns:foaf="...foaf/0.1/" <rdf:RDF xmlns:foaf="...foaf/0.1/" xmlns:rdf="...rdf-syntax-ns#"> xmlns:rdf="...rdf-syntax-ns#"> <rdf:Description rdf:nodeID="x"> <rdf:Description rdf:nodeID="b1"> <foaf:knows rdf:nodeID="y"/> <rdf:type </rdf:Description> rdf:resource=".../Person"/> <rdf:Description rdf:nodeID="x"> <foaf:knows rdf:nodeID="b2"/> <rdf:type rdf:resource=".../Person"/> </rdf:Description> </rdf:Description> <rdf:Description rdf:nodeID="b2"> <rdf:Description rdf:nodeID="y"> <rdf:type <foaf:name>Bob</foaf:name> rdf:resource=".../Person"/> </rdf:Description> <foaf:name>Bob</foaf:name> <rdf:Description rdf:nodeID="y"> </rdf:Description> <rdf:type rdf:resource=".../Person"/> </rdf:RDF> </rdf:Description> </rdf:RDF> 5 / 51
  • 18. Why XQuery/XSLT is not enough: Different syntaxes and serialisations for the same RDF graph: @prefix alice: <alice/> . <rdf:RDF xmlns:foaf="...foaf/0.1/"> Tri plele @prefix foaf: <...foaf/0.1/> . <foaf:Person> urt sto e <foaf:knows> _:b1 rdf:type foaf:Person;r T foaf:knows _:b2. <foaf:Person foaf:name="Bob"/> </foaf:knows> _:b2 rdf:type foaf:Person; </foaf:Person> foaf:name "Bob". </rdf:RDF> <rdf:RDF xmlns:foaf="...foaf/0.1/" <rdf:RDF xmlns:foaf="...foaf/0.1/" xmlns:rdf="...rdf-syntax-ns#"> xmlns:rdf="...rdf-syntax-ns#"> <rdf:Description rdf:nodeID="x"> <rdf:Description rdf:nodeID="b1"> <foaf:knows rdf:nodeID="y"/> <rdf:type </rdf:Description> rdf:resource=".../Person"/> <rdf:Description rdf:nodeID="x"> <foaf:knows rdf:nodeID="b2"/> <rdf:type rdf:resource=".../Person"/> </rdf:Description> </rdf:Description> <rdf:Description rdf:nodeID="b2"> <rdf:Description rdf:nodeID="y"> <rdf:type <foaf:name>Bob</foaf:name> rdf:resource=".../Person"/> </rdf:Description> <foaf:name>Bob</foaf:name> <rdf:Description rdf:nodeID="y"> </rdf:Description> <rdf:type rdf:resource=".../Person"/> </rdf:RDF> </rdf:Description> </rdf:RDF> 5 / 51
  • 19. Why XQuery/XSLT is not enough: Different syntaxes and serialisations for the same RDF graph: @prefix alice: <alice/> . Tri RD <rdf:RDF xmlns:foaf="...foaf/0.1/"> plele @prefix foaf: <...foaf/0.1/> . <foaf:Person> F/ XM urt sto e <foaf:knows> _:b1 rdf:type foaf:Person;r T foaf:knows _:b2. <foaf:Person foaf:name="Bob"/> </foaf:knows> L _:b2 rdf:type foaf:Person; </foaf:Person> foaf:name "Bob". </rdf:RDF> <rdf:RDF xmlns:foaf="...foaf/0.1/" <rdf:RDF xmlns:foaf="...foaf/0.1/" xmlns:rdf="...rdf-syntax-ns#"> xmlns:rdf="...rdf-syntax-ns#"> <rdf:Description rdf:nodeID="x"> <rdf:Description rdf:nodeID="b1"> <foaf:knows rdf:nodeID="y"/> <rdf:type </rdf:Description> rdf:resource=".../Person"/> RDF/XML <foaf:knows rdf:nodeID="b2"/> X ML <rdf:Description rdf:nodeID="x"> <rdf:type rdf:resource=".../Person"/> </rdf:Description> F/ </rdf:Description> <rdf:Description rdf:nodeID="b2"> RD <rdf:Description rdf:nodeID="y"> <rdf:type <foaf:name>Bob</foaf:name> rdf:resource=".../Person"/> </rdf:Description> <foaf:name>Bob</foaf:name> <rdf:Description rdf:nodeID="y"> </rdf:Description> <rdf:type rdf:resource=".../Person"/> </rdf:RDF> </rdf:Description> </rdf:RDF> 5 / 51
  • 20. Why XQuery/XSLT is not enough: Different syntaxes and serialisations for the same RDF graph: @prefix alice: <alice/> . Tri RD <rdf:RDF xmlns:foaf="...foaf/0.1/"> plele @prefix foaf: <...foaf/0.1/> . <foaf:Person> F/ XM urt sto e <foaf:knows> _:b1 rdf:type foaf:Person;r T foaf:knows _:b2. <foaf:Person foaf:name="Bob"/> </foaf:knows> L _:b2 rdf:type foaf:Person; </foaf:Person> foaf:name "Bob". </rdf:RDF> <rdf:RDF xmlns:foaf="...foaf/0.1/" <rdf:RDF xmlns:foaf="...foaf/0.1/" xmlns:rdf="...rdf-syntax-ns#"> xmlns:rdf="...rdf-syntax-ns#"> <rdf:Description rdf:nodeID="x"> <rdf:Description rdf:nodeID="b1"> <foaf:knows rdf:nodeID="y"/> <rdf:type </rdf:Description> rdf:resource=".../Person"/> RDF/XML <foaf:knows rdf:nodeID="b2"/> X ML <rdf:Description rdf:nodeID="x"> <rdf:type rdf:resource=".../Person"/> </rdf:Description> F/ </rdf:Description> <rdf:Description rdf:nodeID="b2"> RD <rdf:Description rdf:nodeID="y"> <rdf:type <foaf:name>Bob</foaf:name> Any transformation needs to take rdf:resource=".../Person"/> <foaf:name>Bob</foaf:name> </rdf:Description> <rdf:Description rdf:nodeID="y"> </rdf:Description> <rdf:type rdf:resource=".../Person"/> into account the different RDF/XML </rdf:RDF> </rdf:Description> </rdf:RDF> representations 5 / 51
  • 21. Why XQuery/XSLT is not enough: Different syntaxes and serialisations for the same RDF graph: @prefix alice: <alice/> . Tri RD <rdf:RDF xmlns:foaf="...foaf/0.1/"> plele @prefix foaf: <...foaf/0.1/> . <foaf:Person> F/ XM urt sto e <foaf:knows> _:b1 rdf:type foaf:Person;r T foaf:knows _:b2. <foaf:Person foaf:name="Bob"/> </foaf:knows> L _:b2 rdf:type foaf:Person; </foaf:Person> foaf:name "Bob". </rdf:RDF> <rdf:RDF xmlns:foaf="...foaf/0.1/" <rdf:RDF xmlns:foaf="...foaf/0.1/" xmlns:rdf="...rdf-syntax-ns#"> xmlns:rdf="...rdf-syntax-ns#"> <rdf:Description rdf:nodeID="x"> <rdf:Description rdf:nodeID="b1"> <foaf:knows rdf:nodeID="y"/> <rdf:type </rdf:Description> rdf:resource=".../Person"/> RDF/XML <foaf:knows rdf:nodeID="b2"/> X ML <rdf:Description rdf:nodeID="x"> <rdf:type rdf:resource=".../Person"/> </rdf:Description> F/ </rdf:Description> <rdf:Description rdf:nodeID="b2"> RD <rdf:Description rdf:nodeID="y"> <rdf:type <foaf:name>Bob</foaf:name> rdf:resource=".../Person"/> </rdf:Description> <foaf:name>Bob</foaf:name> <rdf:Description rdf:nodeID="y"> Or: end up with different transfor- </rdf:Description> </rdf:RDF> <rdf:type rdf:resource=".../Person"/> </rdf:Description> </rdf:RDF> mations for the same RDF data 5 / 51
  • 22. Why SPARQL is not enough: Great for querying RDF! Easy to output Turtle or SPARQL XML results format ... prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.rdf> where { $X vc:FN $FN .} ... but 6 / 51
  • 23. Why SPARQL is not enough: Great for querying RDF! Easy to output Turtle or SPARQL XML results format ... prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.rdf> where { $X vc:FN $FN .} ... but How to produce arbitrary XML??? 6 / 51
  • 24. XSPARQL Transformation language XML and RDF formats (based on XQuery and SPARQL) 7 / 51
  • 25. XSPARQL Transformation language XML and RDF formats (based on XQuery and SPARQL) Lifting and Lowering in a single language 7 / 51
  • 26. Outline Overview
  • 27. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics
  • 28. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL
  • 29. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 30. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 31. XPath XPath is used to locate nodes in XML trees An XPath expression is a sequence of steps separated by /. Each step evaluates to a sequence of nodes. relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> Full spec at http://www.w3.org/TR/xpath20/. Tutorial at http://www.w3schools.com/xpath/default.asp. 8 / 51
  • 32. XPath XPath is used to locate nodes in XML trees An XPath expression is a sequence of steps separated by /. Each step evaluates to a sequence of nodes. relations.xml <relations> relations node <person name="Alice"> is the root ele- <knows>Bob</knows> <knows>Charles</knows> ment </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> Full spec at http://www.w3.org/TR/xpath20/. Tutorial at http://www.w3schools.com/xpath/default.asp. 8 / 51
  • 33. XPath XPath is used to locate nodes in XML trees An XPath expression is a sequence of steps separated by /. Each step evaluates to a sequence of nodes. relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> 3 child elements </person> <person name="Bob"> person with at- <knows>Charles</knows> tribute name </person> <person name="Charles"/> </relations> Full spec at http://www.w3.org/TR/xpath20/. Tutorial at http://www.w3schools.com/xpath/default.asp. 8 / 51
  • 34. XPath XPath is used to locate nodes in XML trees An XPath expression is a sequence of steps separated by /. Each step evaluates to a sequence of nodes. relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> Each person el- </person> ement can have <person name="Charles"/> knows childs </relations> Full spec at http://www.w3.org/TR/xpath20/. Tutorial at http://www.w3schools.com/xpath/default.asp. 8 / 51
  • 35. XPath Steps Step examples /relations Selects the root element relations relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 9 / 51
  • 36. XPath Steps Step examples /relations Selects the root element relations /relations/person Selects all person elements that are children of relations relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 9 / 51
  • 37. XPath Steps Step examples /relations Selects the root element relations /relations/person Selects all person elements that are children of relations //knows Selects all knows elements (in all the document) relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 9 / 51
  • 38. XPath Predicates Predicate examples /relations/person[3] Selects the third person child of relations relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 10 / 51
  • 39. XPath Predicates Predicate examples /relations/person[3] Selects the third person child of relations /relations/person[position()<3] Selects the first two person children of relations relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 10 / 51
  • 40. XPath Predicates Predicate examples /relations/person[3] Selects the third person child of relations /relations/person[position()<3] Selects the first two person children of relations //person[@name=’Alice’] Selects all person elements which the value of the name attribute is ’Alice’ relations.xml <relations> <person name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 10 / 51
  • 41. XQuery XQuery Query language for XML (different requirements than XSLT) functional language typed language Superset of XPath Overview of the formal semantics (Normalisation rules, Static Typing and Dynamic Evaluation) XQuery spec: http://www.w3.org/TR/xquery/. XQuery and XPath Formal Semantics: http://www.w3.org/TR/xquery-semantics/. 11 / 51
  • 42. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 43. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 44. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 45. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 46. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 47. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 48. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 49. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 50. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query Example: Convert our relations data into RDF/XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name where $nameA = "Alice" return <foaf:Person>{$nameA, for $nameB in $person/knows let $friend := <foaf:Person name="{$nameB}"/> order by $nameB return <foaf:knows>{$friend}</foaf:knows> }</foaf:Person> 12 / 51
  • 51. Schematic view on XQuery Prolog: P declare namespace prefix="namespace-URI " Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by XPath-expression Head: R return XML + nested XQuery Query result <foaf:Person xmlns:foaf="http://xmlns.com/foaf/0.1/" name="Alice"> <foaf:knows> <foaf:Person name="Bob"/> </foaf:knows> <foaf:knows> <foaf:Person name="Charles"/> </foaf:knows> </foaf:Person> 12 / 51
  • 52. Positional variable at Query example: add an id attribute to the relations data for $person at $pos in doc("relations.xml")//person return <person id="{$pos}"> {$person/@*, $person/*} </person> $pos refers to the position of $person in the for expression 13 / 51
  • 53. Positional variable at Query example: add an id attribute to the relations data for $person at $pos in doc("relations.xml")//person return <person id="{$pos}"> {$person/@*, $person/*} </person> $pos refers to the position of $person in the for expression Query result <person id="1" name="Alice"> <knows>Bob</knows> <knows>Charles</knows> </person> <person id="2" name="Bob"> <knows>Charles</knows> </person> <person id="3" name="Charles"/> 13 / 51
  • 54. XQuery Formal semantics Normalisation rules Normalisation rules are rewriting rules that translate XQuery into a simplified version (XQuery Core). 14 / 51
  • 55. XQuery Formal semantics Normalisation rules Normalisation rules are rewriting rules that translate XQuery into a simplified version (XQuery Core). Rule application 1 Static Analysis: Apply normalisation rules and static type analysis 2 Dynamic Evaluation Rules: evaluate expressions 14 / 51
  • 56. XQuery Formal semantics Normalisation rules Normalisation rules are rewriting rules that translate XQuery into a simplified version (XQuery Core). Rule application 1 Static Analysis: Apply normalisation rules and static type analysis 2 Dynamic Evaluation Rules: evaluate expressions Environments statEnv contains information needed for performing static type analysis. E.g. varType, funcType, . . . 14 / 51
  • 57. XQuery Formal semantics Normalisation rules Normalisation rules are rewriting rules that translate XQuery into a simplified version (XQuery Core). Rule application 1 Static Analysis: Apply normalisation rules and static type analysis 2 Dynamic Evaluation Rules: evaluate expressions Environments statEnv contains information needed for performing static type analysis. E.g. varType, funcType, . . . dynEnv contains information needed for the evaluation of expressions. E.g. varValue, . . . 14 / 51
  • 58. Semantics - Normalisation rules example for Example for $i in (1, 2), $j in (3, 4) return <pair>{ ($i,$j) }</pair> 15 / 51
  • 59. Semantics - Normalisation rules example for Example for $i in (1, 2), $j in (3, 4) return <pair>{ ($i,$j) }</pair> for Normalised example for $i in (1, 2) return for $j in (3, 4) return <pair>{ ($i,$j) }</pair> 15 / 51
  • 60. Semantics - Normalisation rules example For Normalisation   for $VarName 1 in Expr 1 , · · · ,  $VarName n in Expr n  ReturnClause Expr == for $VarName 1 in [Expr 1]Expr return ··· for $VarName n in [Expr n]Expr [ReturnClause]Expr ] 16 / 51
  • 61. Semantics - Static typing example For Static Type Analysis statEnv Expr 1 : Type 1 statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2 for $Variable in Expr 1 statEnv return Expr 2 : Type 2 · quantifier(Type 1 ) 17 / 51
  • 62. Semantics - Static typing example : means Expr 1 is of type Type 1 For Static Type Analysis statEnv Expr 1 : Type 1 statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2 for $Variable in Expr 1 statEnv return Expr 2 : Type 2 · quantifier(Type 1 ) 17 / 51
  • 63. Semantics - Static typing example + means extend : means Expr 1 is the environment of type Type 1 For Static Type Analysis statEnv Expr 1 : Type 1 statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2 for $Variable in Expr 1 statEnv return Expr 2 : Type 2 · quantifier(Type 1 ) 17 / 51
  • 64. Semantics - Static typing example + means extend : means Expr 1 is the environment of type Type 1 For Static Type Analysis statEnv Expr 1 : Type 1 statEnv + varType(Variable ⇒ Type 1 ) Expr 2 : Type 2 for $Variable in Expr 1 statEnv return Expr 2 : Type 2 · quantifier(Type 1 ) quantifier estimates the number of solutions: *, + or ? 17 / 51
  • 65. Semantics - Dynamic evaluation rules Simple for example for $i in (1, 2) return $i+1 18 / 51
  • 66. Semantics - Dynamic evaluation rules For each result in the expression Simple for example for $i in (1, 2) return $i+1 18 / 51
  • 67. Semantics - Dynamic evaluation rules For each result in the expression Simple for example Variable $i is as- for $i in (1, 2) return $i+1 signed the corre- sponding value 18 / 51
  • 68. Semantics - Dynamic evaluation rules For each result in the expression Simple for example Variable $i is as- for $i in (1, 2) return $i+1 signed the corre- sponding value Return expresion is evaluated 18 / 51
  • 69. Semantics - Dynamic evaluation rules Simple for example for $i in (1, 2) return $i+1 For Dynamic Evaluation (Simplified) dynEnv Expr 1 ⇒ Item1 , . . . , Itemn dynEnv + varValue(Variable ⇒ Item1 ) Expr 2 ⇒ Value 1 ··· dynEnv + varValue(Variable ⇒ Itemn ) Expr 2 ⇒ Value n for $Variable in Expr 1 dynEnv return Expr 2 ⇒ Value 1 , · · · , Value n 18 / 51
  • 70. Semantics - Dynamic evaluation rules Simple for example for $i in (1, 2) return $i+1 ⇒ means Expr 1 eval- uates to the sequence Item1 , . . . , Itemn For Dynamic Evaluation (Simplified) dynEnv Expr 1 ⇒ Item1 , . . . , Itemn dynEnv + varValue(Variable ⇒ Item1 ) Expr 2 ⇒ Value 1 ··· dynEnv + varValue(Variable ⇒ Itemn ) Expr 2 ⇒ Value n for $Variable in Expr 1 dynEnv return Expr 2 ⇒ Value 1 , · · · , Value n 18 / 51
  • 71. Semantics - Dynamic evaluation rules Simple for example For each Itemi2)add Variable for $i in (1, , return $i+1 ⇒ means Expr 1 eval- ⇒ Itemi to dynEnv and uates to the sequence evaluate Expr 2 Item1 , . . . , Itemn For Dynamic Evaluation (Simplified) dynEnv Expr 1 ⇒ Item1 , . . . , Itemn dynEnv + varValue(Variable ⇒ Item1 ) Expr 2 ⇒ Value 1 ··· dynEnv + varValue(Variable ⇒ Itemn ) Expr 2 ⇒ Value n for $Variable in Expr 1 dynEnv return Expr 2 ⇒ Value 1 , · · · , Value n 18 / 51
  • 72. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 73. SPARQL (in 3 slides) SPARQL Query language for RDF SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/. SPARQL 1.1 Tutorial: http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf. 19 / 51
  • 74. SPARQL (in 3 slides) SPARQL Query language for RDF RDF represents data as triples: Subject, Predicate, Object. An RDF Graph is a set of triples. SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/. SPARQL 1.1 Tutorial: http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf. 19 / 51
  • 75. SPARQL (in 3 slides) SPARQL Query language for RDF RDF represents data as triples: Subject, Predicate, Object. An RDF Graph is a set of triples. SPARQL queries RDF data by pattern matching: given a set of triple patterns, finds the corresponding triples in the input graph SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/. SPARQL 1.1 Tutorial: http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf. 19 / 51
  • 76. SPARQL (in 3 slides) SPARQL Query language for RDF RDF represents data as triples: Subject, Predicate, Object. An RDF Graph is a set of triples. SPARQL queries RDF data by pattern matching: given a set of triple patterns, finds the corresponding triples in the input graph Actually, matched against the scoping graph: a graph equivalent to the input graph but does not share any blank nodes with it or the query. SPARQL spec: http://www.w3.org/TR/rdf-sparql-query/. SPARQL 1.1 Tutorial: http://polleres.net/presentations/20101019SPARQL1.1Tutorial.pdf. 19 / 51
  • 77. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 78. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 79. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 80. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 81. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 82. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 83. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 84. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 85. Schematic view on SPARQL Prolog: P prefix prefix: <namespace-URI > Head: C construct { template } select variableList Body: D from / from named <dataset-URI > W where { pattern } M order by expression limit integer > 0 offset integer > 0 Query Example: Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> select $X $FN from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 20 / 51
  • 86. SPARQL select solutions Solutions for SPARQL select queries are substitutions for the variables present in the head (variableList) 21 / 51
  • 87. SPARQL select solutions Solutions for SPARQL select queries are substitutions for the variables present in the head (variableList) Can be represented as XML SPARQL XML Results Format (previous query) <sparql xmlns="http://www.w3.org/2005/sparql-results#"> <head> <variable name="X"/> <variable name="FN"/> </head> <results> <result> <binding name="X"><bnode>b0</bnode></binding> <binding name="FN"><literal>Nuno Lopes</literal></binding> </result> </results> </sparql> 21 / 51
  • 88. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 89. XSPARQL Transformation language Consume and generate XML and RDF 22 / 51
  • 90. XSPARQL Transformation language Consume and generate XML and RDF Syntactic extension of XQuery 22 / 51
  • 91. XSPARQL Transformation language Consume and generate XML and RDF Syntactic extension of XQuery With a formally defined semantics (based on the XQuery semantics) 22 / 51
  • 92. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 93. XSPARQL: Combining XQuery with SPARQL Prolog: P declare namespace prefix="namespace-URI " or prefix prefix: <namespace-URI > Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 offset integer > 0 Head: C construct { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 94. XSPARQL: Combining XQuery with SPARQL prefix Prolog: P declare namespace prefix="namespace-URI " declarations or prefix prefix: <namespace-URI > Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 offset integer > 0 Head: C construct { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 95. XSPARQL: Combining XQuery with SPARQL Prolog: P declare namespace prefix="namespace-URI " or prefix prefix: <namespace-URI > Data input Body: F for var in XPath-expression L let var := XPath-expression (XML or RDF) W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 offset integer > 0 Head: C construct { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 96. XSPARQL: Combining XQuery with SPARQL Prolog: P declare namespace prefix="namespace-URI " or prefix prefix: <namespace-URI > Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 offset integer > 0 Data output Head: C construct { template (with nested XSPARQL) } or (XML or RDF) R return XML + nested XSPARQL 23 / 51
  • 97. XSPARQL: Combining XQuery with SPARQL XQuery or Prolog: P declare namespace prefix="namespace-URI " SPARQL or prefix prefix: <namespace-URI > prefix Body: F for var in XPath-expression L let var := XPath-expression declarations W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 offset integer > 0 Head: C construct { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 98. XSPARQL: Combining XQuery with SPARQL Prolog: P declare namespace prefix="namespace-URI " or prefix prefix: <namespace-URI > Any XQuery Body: F for var in XPath-expression L let var := XPath-expression query W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 offset integer > 0 Head: C construct { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 99. XSPARQL: Combining XQuery with SPARQL Prolog: P declare namespace prefix="namespace-URI " or prefix prefix: <namespace-URI > Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by expression or SPARQLForClause F’ for varlist D from / from named <dataset-URI > represents a W where {pattern } SPARQL query M order by expression limit integer > 0 offset integer > 0 Head: C construct { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 100. XSPARQL: Combining XQuery with SPARQL Prolog: P declare namespace prefix="namespace-URI " or prefix prefix: <namespace-URI > Body: F for var in XPath-expression L let var := XPath-expression W where XPath-expression O order by expression or F’ for varlist D from / from named <dataset-URI > W where {pattern } M order by expression limit integer > 0 construct offset integer > 0 creates RDF Head: C construct output { template (with nested XSPARQL) } or R return XML + nested XSPARQL 23 / 51
  • 101. Query Example - Lifting Convert our relations data into RDF declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } 24 / 51
  • 102. Query Example - Lifting Convert our relations data into RDF declare namespace foaf = "http://xmlns.com/foaf/0.1/"; XQuery for for $person in doc("relations.xml")//person, data selec- $nameA in $person/@name, $nameB in $person/knows tion construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } 24 / 51
  • 103. Query Example - Lifting Convert our relations data into RDF declare namespace foaf = "http://xmlns.com/foaf/0.1/"; construct for $person in doc("relations.xml")//person, clause gen- $nameA in $person/@name, erates RDF $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } 24 / 51
  • 104. Query Example - Lifting Convert our relations data into RDF declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } 24 / 51
  • 105. Query Example - Lifting Convert our relations data into RDF declare namespace foaf = "http://xmlns.com/foaf/0.1/"; Nesting produces for $person in doc("relations.xml")//person, $nameA in $person/@name, an RDF literal $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } 24 / 51
  • 106. Query Example - Lifting Convert our relations data into RDF declare namespace foaf = "http://xmlns.com/foaf/0.1/"; for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } Query result @prefix foaf: <http://xmlns.com/foaf/0.1/> . [ foaf:name "Alice"; a foaf:Person; foaf:knows [ foaf:name "Bob"; a foaf:Person ] ]. [ foaf:name "Alice"; a foaf:Person; foaf:knows [ foaf:name "Charles"; a foaf:Person ] ]. [ foaf:name "Bob"; a foaf:Person; foaf:knows [ foaf:name "Charles"; a foaf:Person ] ]. 24 / 51
  • 107. Nesting in construct clauses Nesting operators {Expr} The result of evaluating Expr will be an RDF literal 25 / 51
  • 108. Nesting in construct clauses Nesting operators {Expr} The result of evaluating Expr will be an RDF literal :{Expr} Same but for RDF blank nodes <{Expr}> and IRIs 25 / 51
  • 109. Query Example - Lifting (II) Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) for $p in $persons let $id := fn:index-of($ids, $p/@name) construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } 26 / 51
  • 110. Query Example - Lifting (II) Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) Keep person iden- for $p in $persons let $id := fn:index-of($ids, $p/@name) tifiers construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } 26 / 51
  • 111. Query Example - Lifting (II) Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) For each person for $p in $persons let $id := fn:index-of($ids, $p/@name) lookup their id construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } 26 / 51
  • 112. Query Example - Lifting (II) Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) The same for each for $p in $persons let $id := fn:index-of($ids, $p/@name) person then know construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } 26 / 51
  • 113. Query Example - Lifting (II) Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) for $p in $persons let $id := fn:index-of($ids, $p/@name) construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } Query result (reformatted output) @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2, _:b3 . _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3 . _:b3 a foaf:Person; foaf:name "Charles" . 26 / 51
  • 114. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 115. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name XML con- return <person name="{$Name}"> { for $FName from <relations.rdf> struction where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 116. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } SPARQL for order by $Name query: “Give me return <person name="{$Name}"> { for $FName from <relations.rdf> persons and their where { $Person foaf:knows $Friend . names” $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 117. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } SPARQL for order by $Name query: “Give me return <person name="{$Name}"> { for $FName from <relations.rdf> persons and their SPARQL variables where { $Person foaf:knows $Friend . names” are $-prefixedfoaf:name $Name. $Person $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 118. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name XML con- return <person name="{$Name}"> { for $FName from <relations.rdf> struction where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 119. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> SPARQL for where { $Person foaf:name $Name } query: “Give me order by $Name return <person name="{$Name}"> the persons each { for $FName from <relations.rdf> one knows” where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 120. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> SPARQL for where { $Person foaf:name $Name } query: “Give me order by $Name return <person name="{$Name}"> the persons each { for $FName from <relations.rdf> one knows” where { $Person foaf:knows $Friend . $Person and $Person foaf:name $Name. $Friend foaf:name $FName. } $Name instanti- return <knows> { $FName }</knows>} ated by the outer </person>} </relations> loop 27 / 51
  • 121. Query Example - Lowering Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name XML con- return <person name="{$Name}"> { for $FName from <relations.rdf> struction where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 27 / 51
  • 122. Query Example - Lowering result Query result <relations> <person name="Alice"> <knows>Charles</knows> <knows>Bob</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 28 / 51
  • 123. Online Demo Online Demo at: http://xsparql.deri.org/demo/ Try it for yourself! 29 / 51
  • 124. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 125. XSPARQL Formal Semantics Extend the XQuery semantics Adding the normalisation, static type and dynamic evaluation rules for the new expressions: SPARQL for clause construct clause 30 / 51
  • 126. Formal semantics types Newly defined types RDFTerm is the type of SPARQL variables, with the subtypes: uri bnode literal 31 / 51
  • 127. Formal semantics types Newly defined types RDFTerm is the type of SPARQL variables, with the subtypes: uri bnode literal RDFGraph will be the type of construct expressions 31 / 51
  • 128. Formal semantics types Newly defined types RDFTerm is the type of SPARQL variables, with the subtypes: uri bnode literal RDFGraph will be the type of construct expressions PatternSolution is a pair (variableName, RDFTerm) representing SPARQL variable bindings 31 / 51
  • 129. SPARQL for - Static Type Analysis statEnv + varType(Variable 1 ⇒ RDFTerm; ··· ; Variable n ⇒ RDFTerm ) ReturnExpr : Type 2 for $Variable 1 · · · $Variable n DatasetClause statEnv where GroupGraphPattern SolutionModifier return ReturnExpr : Type 2 ∗ 32 / 51
  • 130. SPARQL for - Static Type Analysis statEnv + varType(Variable 1 ⇒ RDFTerm; $Variable 1 · · · $Variable n ··· ; are of type RDFTerm Variable n ⇒ RDFTerm ) ReturnExpr : Type 2 for $Variable 1 · · · $Variable n DatasetClause statEnv where GroupGraphPattern SolutionModifier return ReturnExpr : Type 2 ∗ 32 / 51
  • 131. SPARQL for - Static Type Analysis ∗ comes from the sequence of statEnv + varType(Variable 1 ⇒ RDFTerm; results SPARQL ··· ; Variable n ⇒ RDFTerm ) ReturnExpr : Type 2 for $Variable 1 · · · $Variable n DatasetClause statEnv where GroupGraphPattern SolutionModifier return ReturnExpr : Type 2 ∗ 32 / 51
  • 132. Example: Simple SPARQL for Simple SPARQL for example for $s $p $o from <foaf.rdf> where { $s $p $o } return ($s, $p, $o) 33 / 51
  • 133. Example: Simple SPARQL for For each SPARQL result Simple SPARQL for example for $s $p $o from <foaf.rdf> where { $s $p $o } return ($s, $p, $o) 33 / 51
  • 134. Example: Simple SPARQL for For each SPARQL result Simple SPARQL for example Variables are as- for $s $p $o from <foaf.rdf> where { $s $p $o } signed values return ($s, $p, $o) 33 / 51
  • 135. Example: Simple SPARQL for For each SPARQL result Simple SPARQL for example Variables are as- for $s $p $o from <foaf.rdf> where { $s $p $o } signed values return ($s, $p, $o) Return expresion is evaluated 33 / 51
  • 136. SPARQL for - Dynamic Evaluation dynEnv fs:sparql(DatasetClause, GroupGraphPattern, SolutionModifier ) ⇒ PS 1 , . . . , PS m dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); ...; Variable n ⇒ fs:value(PS 1 , Variable n ) ) ReturnExpr ⇒ Value 1 . . . dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); ...; Variable n ⇒ fs:value(PS m , Variable n ) ) ReturnExpr ⇒ Value m for $Variable 1 · · · $Variable n dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 137. SPARQL for - Dynamic Evaluation dynEnv fs:sparql(DatasetClause, GroupGraphPattern, SolutionModifier ) ⇒ PS 1 , . . . , PS m dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); ...; The results of Variable n ⇒ fs:value(PS 1 , Variable n ) the SPARQL ) ReturnExpr ⇒ Value 1 query . . . dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); ...; Variable n ⇒ fs:value(PS m , Variable n ) ) ReturnExpr ⇒ Value m for $Variable 1 · · · $Variable n dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 138. SPARQL for - Dynamic Evaluation dynEnv fs:sparql(DatasetClause, GroupGraphPattern, SolutionModifier ) ⇒ PS 1 , . . . , PS m dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); ...; The results of Variable n ⇒ fs:value(PS 1 , Variable n ) the SPARQL ) ReturnExpr ⇒ Value 1 query . . . dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); ...; fs:sparql evaluates Variable n ⇒ fs:value(PS m , Variable n ) a SPARQL query ) ReturnExpr ⇒ Value m for $Variable 1 · · · $Variable n dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 139. SPARQL for - Dynamic Evaluation dynEnv fs:sparql(DatasetClause, GroupGraphPattern, SolutionModifier ) ⇒ PS 1 , . . . , PS m dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); ...; Variable n ⇒ fs:value(PS 1 , Variable n ) For each PS ) ReturnExpr ⇒ Value 1 add the values . . . of the variables dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); to dynEnv ...; Variable n ⇒ fs:value(PS m , Variable n ) ) ReturnExpr ⇒ Value m for $Variable 1 · · · $Variable n dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 140. SPARQL for - Dynamic Evaluation fs:value selects dynEnv fs:sparql(DatasetClause, GroupGraphPattern, the value of SolutionModifier ) ⇒ PS 1 , . . . , PS m VariabledynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); i from the PS ...; Variable n ⇒ fs:value(PS 1 , Variable n ) For each PS ) ReturnExpr ⇒ Value 1 add the values . . . of the variables dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); to dynEnv ...; Variable n ⇒ fs:value(PS m , Variable n ) ) ReturnExpr ⇒ Value m for $Variable 1 · · · $Variable n dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 141. SPARQL for - Dynamic Evaluation dynEnv fs:sparql(DatasetClause, GroupGraphPattern, SolutionModifier ) ⇒ PS 1 , . . . , PS m dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); ...; Variable n ⇒ fs:value(PS 1 , Variable n ) For each PS ) ReturnExpr ⇒ Value 1 add the values . . . of the variables dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); to dynEnv ...; Variable n ⇒ fs:value(PS m , Variable n ) ) ReturnExpr ⇒ Value m for $Variable 1 · · · $Variable n dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 142. SPARQL for - Dynamic Evaluation dynEnv fs:sparql(DatasetClause, GroupGraphPattern, SolutionModifier ) ⇒ PS 1 , . . . , PS m dynEnv + varValue(Variable 1 ⇒ fs:value(PS 1 , Variable 1 ); ...; Variable n ⇒ fs:value(PS 1 , Variable n ) ) ReturnExpr ⇒ Value 1 . . . The result dynEnv + varValue(Variable 1 ⇒ fs:value(PS m , Variable 1 ); of ...; the expression Variable n ⇒ fs:value(PS m , Variable n ) is the sequence ) ReturnExpr ⇒ Value m of computed for $Variable 1 · · · $Variable n Value s dynEnv where GroupGraphPattern SolutionModifier return ReturnExpr ⇒ Value 1 , . . . , Value m 34 / 51
  • 143. construct expressions construct ConstructTemplate Expr == return fs:evalTemplate [ConstructTemplate ]normaliseTemplate 35 / 51
  • 144. construct expressions [·]normaliseTemplate ex- ] pands any Turtle short- construct ConstructTemplateits argument cuts in Expr == return fs:evalTemplate [ConstructTemplate ]normaliseTemplate 35 / 51
  • 145. construct expressions fs:evalTemplate vali- dates the created triples construct ConstructTemplate Expr == return fs:evalTemplate [ConstructTemplate ]normaliseTemplate 35 / 51
  • 146. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 147. Implementation 36 / 51
  • 148. Implementation Each XSPARQL query is rewritten into an XQuery 36 / 51
  • 149. Implementation Each XSPARQL query is rewritten into an XQuery SPARQLForClauses are translated into SPARQL SELECT queries and executed using a SPARQL engine 36 / 51
  • 150. Lifting: Rewriting to XQuery Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) for $p in $persons let $id := fn:index-of($ids, $p/@name) construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } 37 / 51
  • 151. Lifting: Rewriting to XQuery Convert our relations data into RDF declare namespace foaf="http://xmlns.com/foaf/0.1/"; let $persons := doc("relations.xml")//person let $ids := data($persons/@name) for $p in $persons let $id := fn:index-of($ids, $p/@name) construct { _:b{$id} a foaf:Person; foaf:name {data($p/@name)}. { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } 37 / 51
  • 152. Lifting: Rewriting to XQuery Convert our relations data into RDF (partial) { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } Rewritten XQuery (and re-rewritten for presentation purposes) for $k at $k_pos in $p/knows let $kid := fn:index-of( $ids, $k ) return let $_rdf8 := _xsparql:_binding_term( "_:b", $id, "", "" ) let $_rdf9 := _xsparql:_binding_term( "_:b", $kid, "", "" ) return _xsparql:_serialize(( if (_xsparql:_validSubject($_rdf8) and _xsparql:_validObject($_rdf9)) then ($_rdf8, " foaf:knows ", _xsparql:_rdf_term( $_rdf9 ), " .&#xA;") else "") ) ) ) 37 / 51
  • 153. Lifting: Rewriting to XQuery Convert our relations data into RDF (partial) { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } Rewritten XQuery (and re-rewritten for presentation purposes) for $k at $k_pos in $p/knows let $kid := fn:index-of( $ids, $k ) return let $_rdf8 := _xsparql:_binding_term( "_:b", $id, "", "" ) let $_rdf9 := _xsparql:_binding_term( "_:b", $kid, "", "" ) return _xsparql:_serialize(( Create (_xsparql:_validSubject($_rdf8) and _xsparql:_validObject($_rdf9)) if variables of then type RDFTerm " foaf:knows ", _xsparql:_rdf_term( $_rdf9 ), " .&#xA;") ($_rdf8, for eachelse "") constructed ) ) ) term 37 / 51
  • 154. Lifting: Rewriting to XQuery Convert our relations data into RDF (partial) { for $k in $p/knows let $kid := fn:index-of($ids, $k) construct { _:b{$id} foaf:knows _:b{$kid} } } } Rewritten XQuery (and re-rewritten for presentation purposes) If all the variables for $k at $k_pos in $p/knows represent valid RDF let $kid := fn:index-of( $ids, $k ) return terms for the given let $_rdf8 := _xsparql:_binding_term( "_:b", position "" )output $id, "", we let $_rdf9 := _xsparql:_binding_term( "_:b", the triple "" ) $kid, "", return _xsparql:_serialize(( if (_xsparql:_validSubject($_rdf8) and _xsparql:_validObject($_rdf9)) then ($_rdf8, " foaf:knows ", _xsparql:_rdf_term( $_rdf9 ), " .&#xA;") else "") ) ) ) 37 / 51
  • 155. Handling blank nodes in CONSTRUCT Construct foaf:Person prefix foaf: <http://xmlns.com/foaf/0.1/> for $id in ("a","b","c","d") construct { _:Person a foaf:Person } 38 / 51
  • 156. Handling blank nodes in CONSTRUCT Construct foaf:Person Blank nodes prefix foaf: <http://xmlns.com/foaf/0.1/> should be different for $id in ("a","b","c","d") for each solution construct { _:Person a foaf:Person } 38 / 51
  • 157. Handling blank nodes in CONSTRUCT Construct foaf:Person prefix foaf: <http://xmlns.com/foaf/0.1/> for $id in ("a","b","c","d") construct { _:Person a foaf:Person } Append position variable to the XQuery rewriting blank node for $id at $id_pos in ("a", "b", "c", "d") let $_rdf0 := _xsparql:_binding_term(fn:concat("_:Person","_",$id_pos)) return _xsparql:_serialize( ( if (_xsparql:_validSubject( $_rdf0 )) then ($_rdf0, " ", "a", " ", "foaf:Person", " .&#xA;") else "") ) 38 / 51
  • 158. Handling blank nodes in CONSTRUCT Construct foaf:Person prefix foaf: <http://xmlns.com/foaf/0.1/> for $id in ("a","b","c","d") construct { _:Person a foaf:Person } Query result @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:Person_1 a foaf:Person . _:Person_2 a foaf:Person . _:Person_3 a foaf:Person . _:Person_4 a foaf:Person . 38 / 51
  • 159. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 39 / 51
  • 160. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 39 / 51
  • 161. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name Rewriting to XQuery let $_aux_results3 := _xsparql:_sparqlQuery( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT $Person $Name from <relations.rdf> where { $Person foaf:name $Name . } order by $Name " ) for $_aux_result3 at $_aux_result3_pos in $_aux_results3 let $Person := _xsparql:_resultNode( $_aux_result3, "Person" ) let $Name := _xsparql:_resultNode( $_aux_result3, "Name" ) 40 / 51
  • 162. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name Rewriting to XQuery let $_aux_results3 := _xsparql:_sparqlQuery( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT $Person $Name from <relations.rdf> where { $Person foaf:name $Name . } order by $Name " ) for $_aux_result3 at $_aux_result3_pos in $_aux_results3 let $Person := _xsparql:_resultNode( $_aux_result3, "Person" ) let $Name := _xsparql:_resultNode( $_aux_result3, "Name" ) 40 / 51
  • 163. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name Rewriting to XQuery let $_aux_results3 := _xsparql:_sparqlQuery( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT $Person $Name from <relations.rdf> where { $Person foaf:name $Name . } order by $Name " ) for $_aux_result3 at $_aux_result3_pos in $_aux_results3 let $Person := _xsparql:_resultNode( $_aux_result3, "Person" ) let $Name := _xsparql:_resultNode( $_aux_result3, "Name" ) 40 / 51
  • 164. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name Rewriting to XQuery let $_aux_results3 := _xsparql:_sparqlQuery( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT $Person $Name from <relations.rdf> where { $Person foaf:name $Name . } order by $Name " ) for $_aux_result3 at $_aux_result3_pos in $_aux_results3 let $Person := _xsparql:_resultNode( $_aux_result3, "Person" ) let $Name := _xsparql:_resultNode( $_aux_result3, "Name" ) 40 / 51
  • 165. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $Person $Name from <relations.rdf> sparqlQuery where { $Person foaf:name $Name } order by $Name Implementation: HTTP call, Java extension Rewriting to XQuery let $_aux_results3 := _xsparql:_sparqlQuery( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT $Person $Name from <relations.rdf> where { $Person foaf:name $Name . } order by $Name " ) for $_aux_result3 at $_aux_result3_pos in $_aux_results3 let $Person := _xsparql:_resultNode( $_aux_result3, "Person" ) let $Name := _xsparql:_resultNode( $_aux_result3, "Name" ) 40 / 51
  • 166. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 41 / 51
  • 167. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } Rewriting to XQuery let $_aux_results5 := _xsparql:_sparqlQuery( fn:concat( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT $FName from <relations.rdf> where { ", $Person, " foaf:knows $Friend . ", $Person, " foaf:name ", $Name, " . $Friend foaf:name $FName . } " ) ) for $_aux_result5 at $_aux_result5_pos in $_aux_results5 let $FName := _xsparql:_resultNode( $_aux_result5, "FName" ) 41 / 51
  • 168. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } Rewriting to XQuery let $_aux_results5 := _xsparql:_sparqlQuery( fn:concat( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> $Person and SELECT $FName from <relations.rdf> where { ", $Person, " foaf:knows $Friend . ", $Name instanti- $Person, " foaf:name ", $Name, " . ated by the outer $Friend foaf:name $FName . } " ) ) loop for $_aux_result5 at $_aux_result5_pos in $_aux_results5 let $FName := _xsparql:_resultNode( $_aux_result5, "FName" ) 41 / 51
  • 169. Lowering: Rewriting to XQuery Convert FOAF RDF data into XML (partial) for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } Rewriting to XQuery let $_aux_results5 := _xsparql:_sparqlQuery( fn:concat( "PREFIX foaf: <http://xmlns.com/foaf/0.1/> Replaced by their SELECT $FName from <relations.rdf> where { ", $Person, " foaf:knows $Friend . ", value in the query $Person, " foaf:name ", $Name, " . string $Friend foaf:name $FName . } " ) ) for $_aux_result5 at $_aux_result5_pos in $_aux_results5 let $FName := _xsparql:_resultNode( $_aux_result5, "FName" ) 41 / 51
  • 170. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 171. Lowering Example Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName from <relations.rdf> where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 42 / 51
  • 172. Lowering Example Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> $Person and where { $Person foaf:name $Name } $Name instanti- order by $Name return <person name="{$Name}"> ated by the outer { for $FName from <relations.rdf> loop where { $Person foaf:knows $Friend . $Person foaf:name $Name. $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 42 / 51
  • 173. Lowering Example Convert FOAF RDF data into XML declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName from <relations.rdf> If $Person is a where { $Person foaf:knows $Friend . $Person foaf:name $Name. blank node, query $Friend foaf:name $FName. } joining is done by return <knows> { $FName }</knows>} </person>} the $Name variable </relations> 42 / 51
  • 174. Problem with the Lowering example @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2. _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3. _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3. _:b3 a foaf:Person; foaf:name "Charles". 43 / 51
  • 175. Problem with the Lowering example @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2. _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3. _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3. _:b3 a foaf:Person; foaf:name "Charles". 43 / 51
  • 176. Problem with the Lowering example @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2. _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3. _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3. _:b3 a foaf:Person; foaf:name "Charles". <relations> <person name="Alice"> <knows>Charles</knows> <knows>Bob</knows> </person> <person name="Alice"> <knows>Charles</knows> <knows>Bob</knows> </person> <person name="Bob"><knows>Charles</knows></person> <person name="Charles"/> </relations> 43 / 51
  • 177. Problem with the Lowering example @prefix foaf: <http://xmlns.com/foaf/0.1/> . _:b1 a foaf:Person; foaf:name "Alice"; foaf:knows _:b2. _:b4 a foaf:Person; foaf:name "Alice"; foaf:knows _:b3. _:b2 a foaf:Person; foaf:name "Bob"; foaf:knows _:b3. _:b3 a foaf:Person; foaf:name "Charles". <relations> <person name="Alice"> <knows>Charles</knows> <knows>Bob</knows> </person> <person name="Alice"> <knows>Charles</knows> <knows>Bob</knows> </person> <person name="Bob"><knows>Charles</knows></person> <person name="Charles"/> </relations> 43 / 51
  • 178. Scoped Dataset Scoping Graph SPARQL query solutions are taken from the scoping graph: a graph that is equivalent to the active graph but does not share any blank nodes with it or any graph pattern within the query. 44 / 51
  • 179. Scoped Dataset Scoping Graph SPARQL query solutions are taken from the scoping graph: a graph that is equivalent to the active graph but does not share any blank nodes with it or any graph pattern within the query. Scoped Dataset The XSPARQL scoped dataset allows to make SPARQL queries over the previous scoping graph, keeping the same blank node assignments 44 / 51
  • 180. Scoped Dataset Example Convert FOAF RDF data into XML (Scoped Dataset) declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 45 / 51
  • 181. Scoped Dataset Example Convert FOAF RDF data into XML (Scoped Dataset) declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> Keep the same where { $Person foaf:name $Name } active dataset order by $Name return <person name="{$Name}"> that was last used { for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 45 / 51
  • 182. Scoped Dataset Example Convert FOAF RDF data into XML (Scoped Dataset) declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>} </relations> 45 / 51
  • 183. Scoped Dataset Example Convert FOAF RDF data into XML (Scoped Dataset) declare namespace foaf = "http://xmlns.com/foaf/0.1/"; <relations> { for $Person $Name from <relations.rdf> where { $Person foaf:name $Name } order by $Name return <person name="{$Name}"> { for $FName Can no longer where { $Person foaf:knows $Friend . be implemented $Friend foaf:name $FName. } return <knows> { $FName }</knows>} as rewriting to a </person>} SPARQL query </relations> 45 / 51
  • 184. Scoped Dataset Example Query output <relations> <person name="Alice"> <knows>Charles</knows> </person> <person name="Alice"> <knows>Bob</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 45 / 51
  • 185. Scoped Dataset Example Query output <relations> <person name="Alice"> <knows>Charles</knows> </person> <person name="Alice"> <knows>Bob</knows> </person> <person name="Bob"> <knows>Charles</knows> </person> <person name="Charles"/> </relations> 45 / 51
  • 186. Constructed Dataset Assign the result of a construct query to a variable The variable can then be used as the dataset of a SPARQL query Lifting and Lowering query :) let $ds := for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } return <relations>{ for $Person $Name from $ds where { $Person foaf:name $Name } order by $Name return <person name="{$Name}">{ for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>}</relations> 46 / 51
  • 187. Constructed Dataset Assign the result of a construct query to a variable The variable can then be used as the dataset of a SPARQL query Lifting and Lowering query :) let $ds := for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } return <relations>{ for $Person $Name from $ds where { $Person foaf:name $Name } order by $Name return <person name="{$Name}">{ for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>}</relations> 46 / 51
  • 188. Constructed Dataset Assign the result of a construct query to a variable The variable can then be used as the dataset of a SPARQL query Lifting and Lowering query :) let $ds := for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } return <relations>{ for $Person $Name from $ds where { $Person foaf:name $Name } order by $Name return <person name="{$Name}">{ for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>}</relations> 46 / 51
  • 189. Constructed Dataset Assign the result of a construct query to a variable The variable can then be used as the dataset of a SPARQL query Lifting and Lowering query :) let $ds := for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } return <relations>{ forthe $ds contains $Person $Name from $ds RDF Dataset where { $Person foaf:name $Name } order by $Name return <person name="{$Name}">{ for $FName where { $Person foaf:knows $Friend . $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>}</relations> 46 / 51
  • 190. Constructed Dataset Assign the result of a construct query to a variable The variable can then be used as the dataset of a SPARQL query Lifting and Lowering query :) let $ds := for $person in doc("relations.xml")//person, $nameA in $person/@name, $nameB in $person/knows construct { [ foaf:name {data($nameA)}; a foaf:Person ] foaf:knows [ foaf:name {data($nameB)}; a foaf:Person ]. } return <relations>{ for $Person $Name from $ds where { $Person foaf:name $Name } order by $Name return <personLater used in a for $FName name="{$Name}">{ where { $Person foaf:knows $Friend . from clause $Friend foaf:name $FName. } return <knows> { $FName }</knows>} </person>}</relations> 46 / 51
  • 191. Outline Overview XPath & XQuery XPath XQuery XQuery Semantics SPARQL XSPARQL Syntax Semantics Implementation XSPARQL Features Query examples
  • 192. More expressive SPARQL Convert between different RDF vocabularies (SPARQL) prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { $X foaf:name $FN.} from <vCard.ttl> where { $X vc:FN $FN .} order by $FN limit 1 offset 1 47 / 51
  • 193. More expressive SPARQL Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> construct { _:b foaf:name {fn:concat($N," ", $F)}.} from <vCard.rdf> where { $P vc:Given $N. $P vc:Family $F. } 47 / 51
  • 194. More expressive SPARQL Convert between different RDF vocabularies Construction prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> of new values not available in construct { _:b foaf:name {fn:concat($N," ", $F)}.} from <vCard.rdf> SPARQL 1.0 where { $P vc:Given $N. $P vc:Family $F. } 47 / 51
  • 195. More expressive SPARQL Convert between different RDF vocabularies prefix vc: <http://www.w3.org/2001/vcard-rdf/3.0#> prefix foaf: <http://xmlns.com/foaf/0.1/> XSPARQL pro- construct { _:b foaf:name {fn:concat($N," ", $F)}.} vides you with from <vCard.rdf> where { $P vc:Given $N. $P vc:Family $F. } all the XQuery functions 47 / 51
  • 196. Query Example - KML Lowering Create a KML file from RDF Geolocation data prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> <kml xmlns="http://www.opengis.net/kml/2.2">{ for $person $name $long $lat from <http://nunolopes.org/foaf.rdf> where { $person a foaf:Person; foaf:name $name; foaf:based_near [ a geo:Point; geo:long $long; geo:lat $lat ] } return <Placemark> <name>{fn:concat("Location of ", $name)}</name> <Point> <coordinates>{fn:concat($long, ",", $lat, ",0")} </coordinates> </Point> </Placemark> }</kml> 48 / 51
  • 197. Query Example - KML Lowering Create a KML file from RDF Geolocation data prefix foaf: <http://xmlns.com/foaf/0.1/> SPARQL: Per- prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> sons and their <kml xmlns="http://www.opengis.net/kml/2.2">{ geographic lo- for $person $name $long $lat from <http://nunolopes.org/foaf.rdf> cations where { $person a foaf:Person; foaf:name $name; foaf:based_near [ a geo:Point; geo:long $long; geo:lat $lat ] } return <Placemark> <name>{fn:concat("Location of ", $name)}</name> <Point> <coordinates>{fn:concat($long, ",", $lat, ",0")} </coordinates> </Point> </Placemark> }</kml> 48 / 51
  • 198. Query Example - KML Lowering Create a KML file from RDF Geolocation data prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> <kml xmlns="http://www.opengis.net/kml/2.2">{ for $person $name $long $lat XML repre- from <http://nunolopes.org/foaf.rdf> senting the where { $person a foaf:Person; foaf:name $name; specific KML foaf:based_near [ a geo:Point; geo:long $long; geo:lat $lat ] } file structure return <Placemark> <name>{fn:concat("Location of ", $name)}</name> <Point> <coordinates>{fn:concat($long, ",", $lat, ",0")} </coordinates> </Point> </Placemark> }</kml> 48 / 51
  • 199. Query Example - KML Lowering Create a KML file from RDF Geolocation data prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> <kml xmlns="http://www.opengis.net/kml/2.2">{ for $person $name $long $lat from <http://nunolopes.org/foaf.rdf> where { $person a foaf:Person; foaf:name $name; foaf:based_near [ a geo:Point; geo:long $long; geo:lat $lat ] } return <Placemark> <name>{fn:concat("Location of ", $name)}</name> <Point> <coordinates>{fn:concat($long, ",", $lat, ",0")} </coordinates> </Point> </Placemark> }</kml> 48 / 51
  • 200. Query Example - KML Lifting Create RDF Geolocation data from a KML file prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix kml: <http://earth.google.com/kml/2.0> let $loc := "Departamento de Ingeneria Matematica, U. de Chile" for $place in doc(fn:concat("http://maps.google.com/?q=", fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml")) let $geo := fn:tokenize($place//kml:coordinates, ",") construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]}; geo:lat {$geo[2]} ] } 49 / 51
  • 201. Query Example - KML Lifting Create RDF Geolocation data from a KML file prefix foaf: <http://xmlns.com/foaf/0.1/> Google doesn’t know Departa- mento de Ciencias de la Com- prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix kml: <http://earth.google.com/kml/2.0> putacion?? let $loc := "Departamento de Ingeneria Matematica, U. de Chile" for $place in doc(fn:concat("http://maps.google.com/?q=", fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml")) let $geo := fn:tokenize($place//kml:coordinates, ",") construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]}; geo:lat {$geo[2]} ] } 49 / 51
  • 202. Query Example - KML Lifting Create RDF Geolocation data from a KML file Ask Google prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> Maps for the prefix kml: <http://earth.google.com/kml/2.0> KML descrip- tion let $loc := "Departamento de Ingeneria Matematica, U. de Chile" for $place in doc(fn:concat("http://maps.google.com/?q=", fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml")) let $geo := fn:tokenize($place//kml:coordinates, ",") construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]}; geo:lat {$geo[2]} ] } 49 / 51
  • 203. Query Example - KML Lifting Create RDF Geolocation data from a KML file prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix kml: <http://earth.google.com/kml/2.0> Construct the let $loc := "Departamento de Ingeneria Matematica, U. de Chile" for $place in doc(fn:concat("http://maps.google.com/?q=", updated RDF graph fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml")) let $geo := fn:tokenize($place//kml:coordinates, ",") construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]}; geo:lat {$geo[2]} ] } 49 / 51
  • 204. Query Example - KML Lifting Create RDF Geolocation data from a KML file prefix foaf: <http://xmlns.com/foaf/0.1/> prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> prefix kml: <http://earth.google.com/kml/2.0> let $loc := "Departamento de Ingeneria Matematica, U. de Chile" for $place in doc(fn:concat("http://maps.google.com/?q=", fn:encode-for-uri($loc),"&amp;num=1&amp;output=kml")) let $geo := fn:tokenize($place//kml:coordinates, ",") construct { [] foaf:based_near [ a geo:Point; geo:long {$geo[1]}; geo:lat {$geo[2]} ] } Output RDF data @prefix geo: <http://www.w3.org/2003/01/geo/wgs84_pos#> . @prefix foaf: <http://xmlns.com/foaf/0.1/> . [ foaf:based_near [ a geo:Point ; geo:long "-70.664448" ; geo:lat "-33.457286" ] ] . 49 / 51
  • 205. Queries over Linked Data Give me all pairs of co-authors and their joint publications. let $ds := for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres> where { $pub dc:creator [] } construct { { for * from $pub where { $p dc:creator $o . } construct { $p dc:creator $o } } } let $allauthors := distinct-values( for $o from $ds where {$p dc:creator $o} order by $o return $o) for $auth at $auth_pos in $allauthors for $coauth in $allauthors[position() > $auth_pos] let $commonPubs := count( { for $pub from $ds where { $pub dc:creator $auth, $coauth } return $pub } ) where ($commonPubs > 0) construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] } 50 / 51
  • 206. Queries over Linked Data Give me all pairs of co-authors and their joint publications. let $ds := for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres> where { $pub dc:creator [] } construct { { for * from $pub where { $p dc:creator $o . } construct { $p dc:creator $o } } } let $allauthors := distinct-values( Find all the co- for $o from $ds where {$p dc:creator $o} order by $o return $o) authors of Axel for $auth at $auth_pos in $allauthors Polleres for $coauth in $allauthors[position() > $auth_pos] let $commonPubs := count( { for $pub from $ds where { $pub dc:creator $auth, $coauth } return $pub } ) where ($commonPubs > 0) construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] } 50 / 51
  • 207. Queries over Linked Data Give me all pairs of co-authors and their joint publications. let $ds := for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres> where { $pub dc:creator [] } And the dis- construct { { for * from $pub where { $p dc:creator $o . } construct { $p dc:creator $o } } } tinct names let $allauthors := distinct-values( for $o from $ds where {$p dc:creator $o} order by $o return $o) for $auth at $auth_pos in $allauthors for $coauth in $allauthors[position() > $auth_pos] let $commonPubs := count( { for $pub from $ds where { $pub dc:creator $auth, $coauth } return $pub } ) where ($commonPubs > 0) construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] } 50 / 51
  • 208. Queries over Linked Data Give me all pairs of co-authors and their joint publications. let $ds := for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres> where { $pub dc:creator [] } construct { { for * from $pub where { $p dc:creator $o . } construct { $p dc:creator $o } } } For each dis- let $allauthors := distinct-values( tinct pair of for $o from $ds where {$p dc:creator $o} order by $o return $o) authors for $auth at $auth_pos in $allauthors for $coauth in $allauthors[position() > $auth_pos] let $commonPubs := count( { for $pub from $ds where { $pub dc:creator $auth, $coauth } return $pub } ) where ($commonPubs > 0) construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] } 50 / 51
  • 209. Queries over Linked Data Give me all pairs of co-authors and their joint publications. let $ds := for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres> where { $pub dc:creator [] } construct { { for * from $pub where { $p dc:creator $o . } construct { $p dc:creator $o } } } let $allauthors := distinct-values( Count the for $o from $ds where {$p dc:creator $o} order by $o return $o) number of for $auth at $auth_pos in $allauthors their shared for $coauth in $allauthors[position() > $auth_pos] let $commonPubs := count( publications { for $pub from $ds where { $pub dc:creator $auth, $coauth } return $pub } ) where ($commonPubs > 0) construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] } 50 / 51
  • 210. Queries over Linked Data Give me all pairs of co-authors and their joint publications. let $ds := for * from <http://dblp.l3s.de/d2r/resource/authors/Axel_Polleres> where { $pub dc:creator [] } construct { { for * from $pub where { $p dc:creator $o . } construct { $p dc:creator $o } } } let $allauthors := distinct-values( for $o from $ds where {$p dc:creator $o} order by $o return $o) for $auth at $auth_pos in $allauthors for $coauth in $allauthors[position() > $auth_pos] let $commonPubs := count( { for $pub from $ds Create the where { $pub dc:creator $auth, $coauth } return $pub } ) RDF output where ($commonPubs > 0) construct { [ :author $auth; :author $coauth; :commonPubs $commonPubs ] } 50 / 51
  • 211. The end... http://xsparql.deri.org/ Downloads: http://sourceforge.net/projects/xsparql/ new version coming very soon! Mailing List: xsparql-discussion@lists.sourceforge.net This tutorial: http://nunolopes.org/presentations/2010.12.17- XSPARQLTutorial.pdf 51 / 51
  • 212. Outline Optimisations
  • 213. Optimisations & Benchmarks Data Benchmark suite for XML http://www.xml-benchmark.org/ Provides data generator and 20 benchmark queries Data simulates an auction website, containing people, items and auctions 52 / 51
  • 214. Optimisations & Benchmarks Data Benchmark suite for XML http://www.xml-benchmark.org/ Provides data generator and 20 benchmark queries Data simulates an auction website, containing people, items and auctions Converted XML data to RDF 52 / 51
  • 215. Optimisations & Benchmarks Data Benchmark suite for XML http://www.xml-benchmark.org/ Provides data generator and 20 benchmark queries Data simulates an auction website, containing people, items and auctions Converted XML data to RDF Queries written using XSPARQL 52 / 51
  • 216. Optimisations & Benchmarks Data Benchmark suite for XML http://www.xml-benchmark.org/ Provides data generator and 20 benchmark queries Data simulates an auction website, containing people, items and auctions Converted XML data to RDF Queries written using XSPARQL Query example List the names of persons and the number of items they bought 52 / 51
  • 217. Benchmark Query example XQuery let $auction := doc("input.xml") return for $p in $auction/site/people/person let $a := for $t in $auction/site/closed_auctions/closed_auction where $t/buyer/@person = $p/@id return $t return <item person="{$p/name/text()}">{count($a)}</item> 53 / 51
  • 218. Benchmark Query example XQuery let $auction := doc("input.xml") return for $p in $auction/site/people/person let $a := for $t in $auction/site/closed_auctions/closed_auction where $t/buyer/@person = $p/@id return $t return <item person="{$p/name/text()}">{count($a)}</item> Translation to XSPARQL for $id $name from <input.rdf> where { $person a foaf:Person ; :id $id ; foaf:name $name . } return <item person="{$name}">{ let $x := for * from $rdf where { $ca a :ClosedAuction ; :buyer [ :id $id ] . } return $ca return count($x) }</item> 53 / 51
  • 219. Rewriting to XQuery Unoptimised Version let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> WHERE { $person a foaf:Person ; :id $id ; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ let $x := let $_aux_results2 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca FROM <input.rdf> WHERE { $ca a :ClosedAuction ; :buyer [:id ", $id, "] .}")) for $_aux_result2 at $_aux_result2_pos in $_aux_results2 let $ca := _xsparql:_resultNode( $_aux_result2, "ca" ) return $ca return count( $x ) }</item> 54 / 51
  • 220. Rewriting to XQuery Unoptimised Version let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> WHERE { $person a foaf:Person ; :id $id ; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) Outer SPARQL query let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ let $x := let $_aux_results2 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca FROM <input.rdf> WHERE { $ca a :ClosedAuction ; :buyer [:id ", $id, "] .}")) for $_aux_result2 at $_aux_result2_pos in $_aux_results2 let $ca := _xsparql:_resultNode( $_aux_result2, "ca" ) return $ca return count( $x ) }</item> 54 / 51
  • 221. Rewriting to XQuery Unoptimised Version let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> WHERE { $person a foaf:Person ; :id $id ; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ Inner SPARQL query let $x := let $_aux_results2 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca FROM <input.rdf> WHERE { $ca a :ClosedAuction ; :buyer [:id ", $id, "] .}")) for $_aux_result2 at $_aux_result2_pos in $_aux_results2 let $ca := _xsparql:_resultNode( $_aux_result2, "ca" ) return $ca return count( $x ) }</item> 54 / 51
  • 222. Rewriting to XQuery Optimised Version (nested loop join) let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca $id from <input.rdf> WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") ) let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> WHERE { $person a foaf:Person; :id $id; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ let $x := for $_aux_result4 at $_aux_result4_pos in $_aux_results4 where $id = _xsparql:_resultNode( $_aux_result4, "id" ) return _xsparql:_resultNode( $_aux_result4, "ca" ) return count( $x ) }</item> 54 / 51
  • 223. Rewriting to XQuery Optimised Version (nested loop join) let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca $id from <input.rdf> WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") ) let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> Inner SPARQL query WHERE { $person a foaf:Person; :id $id; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ let $x := for $_aux_result4 at $_aux_result4_pos in $_aux_results4 where $id = _xsparql:_resultNode( $_aux_result4, "id" ) return _xsparql:_resultNode( $_aux_result4, "ca" ) return count( $x ) }</item> 54 / 51
  • 224. Rewriting to XQuery Optimised Version (nested loop join) let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca $id from <input.rdf> WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") ) let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> WHERE { $person a foaf:Person; :id $id; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) Outer SPARQL query let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ let $x := for $_aux_result4 at $_aux_result4_pos in $_aux_results4 where $id = _xsparql:_resultNode( $_aux_result4, "id" ) return _xsparql:_resultNode( $_aux_result4, "ca" ) return count( $x ) }</item> 54 / 51
  • 225. Rewriting to XQuery Optimised Version (nested loop join) let $_aux_results4 := _xsparql:_sparqlQuery( fn:concat( "SELECT $ca $id from <input.rdf> WHERE { $ca a :ClosedAuction; :buyer [:id $id ] .}") ) let $_aux_results0 := _xsparql:_sparqlQuery( fn:concat( "SELECT $id $name from <input.rdf> WHERE { $person a foaf:Person; :id $id; foaf:name $name .}")) for $_aux_result0 at $_aux_result0_pos in $_aux_results0 let $id := _xsparql:_resultNode( $_aux_result0, "id" ) let $name := _xsparql:_resultNode( $_aux_result0, "name" ) return <item person="{$name}">{ let $x := for $_aux_result4 at $_aux_result4_pos in $_aux_results4 where $id = _xsparql:_resultNode( $_aux_result4, "id" ) return _xsparql:_resultNode( $_aux_result4, "ca" ) return count( $x ) }</item> 54 / 51
  • 226. Preliminary results look promising... 30000 XSPARQL optimised version 25000 20000 Time (sec) 15000 10000 5000 0 5 10 20 50 100 Dataset size (MB) Figure: optimisation query 08 55 / 51