RDF Query Examples

Short collection of RDF Queries taken from RDF Query and Rules: A Framework and Survey and XQuery examples provided by Jerome Simeon, Damian Steer, and Jonathan Robie's The Syntactic Web. Thanks to Paul Turner for helping put the slides together.

Eric Prud'hommeaux
11 Dec, 2003
Keio University, Japan

$Revision: 1.2 $ $Date: 2003/12/20 00:26:01 $

Accessing RDF Data With XQuery

Problem: RDF has flexible serialization.

Example #1 RDF Syntax:

<rdf:Description rdf:about="http://example.com/svc1">
   <rdf:type>
      <rdf:Description rdf:about="http://schemas.xmlsoap.org/wsdl/service"/>
   </rdf:type>
   <wsdl:hasPort>
      <rdf:Description rdf:about="http://example.com/prt1"/>
   </wsdl:hasPort>
</rdf:Description>

Example #2 Abreviated Syntax:

<rdf:Description rdf:about="http://example.com/svc1">
   <rdf:type rdf:resource="http://schemas.xmlsoap.org/wsdl/service"/>
   <wsdl:hasPort rdf:resource="http://example.com/prt1"/>
</rdf:Description>

Alternate Syntaxes

The same solution for accessing flexible serialization maybe be use for accessing alternate syntaxes.

n3:

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix wsdl: <http://schemas.xmlsoap.org/wsdl/> .
@prefix ex: <http://example.com/> .
ex:svc1 rdf:type wsdl:service .
ex:svc1 wsdl:hasPort ex:prt1 .

ntriples:

http://example.com/svc1 http://www.w3.org/1999/02/22-rdf-syntax-ns#type http://schemas.xmlsoap.org/wsdl/service .
http://example.com/svc1 http://schemas.xmlsoap.org/wsdl/hasPort http://example.com/prt1 .

N3

N3 is a rule language, used here for query: (survey example)

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix wsdl: <http://schemas.xmlsoap.org/wsdl/> .
@prefix wssoap: <http://schemas.xmlsoap.org/wsdl/soap/> .
@prefix agg: <http://example.com/xmlns/aggregation-demo#>.
this log:forAll :service, :port, :binding, :bindingName.
{
 :service rdf:type wsdl:service.
 :service wsdl:hasPort :port.
 :port wsdl:binding :binding.
 :binding wssoap:style wssoap:document.
 :binding wsdl:name :bindingName).
} log:implies {
 (:service, :bindingName) a agg:Q1Answer.
} .

RDQL

RDQL, Squish, Inkling are more SQL-ish: (survey example)

SELECT ?port, ?binding
FROM <http://www.w3.org/2001/03/19-annotated-RDF-WSDL.rdf>
WHERE
  (?service   rdf:type      wsdl:service) 
  (?service   wsdl:hasPort  ?port)
  (?port      wsdl:binding  ?binding)
  (?binding   wsdl:name     ?bindingName)
  (?binding   wsdl:hasBinding  ?x)
  (?x         wssoap:style  wssoap:document)
USING
  wsdl FOR <http://schemas.xmlsoap.org/wsdl/> ,
  wssoap FOR <http://schemas.xmlsoap.org/wsdl/soap/>

SeRQL

This recently designed query language conveys some structure in the syntax: (survey example)

SELECT port, binding
FROM
  {}     <rdf:type>     <wsdl:service>;
         <wsdl:hasPort> {port}
  {port} <wsdl:binding> {binding} <wsdl:name>       {bindingName};
                                  <wsdl:hasBinding> {} <wssoap:style>  <wssoap:document>
USING NAMESPACE
  rdf = <!http://www.w3.org/1999/02/22-rdf-syntax-ns#> ,
  wsdl = <!http://schemas.xmlsoap.org/wsdl/> ,
  wssoap = <!http://schemas.xmlsoap.org/wsdl/soap/>

TreeHugger

TreeHugger is a recently developed use of XQuery to access RDF data: (survey example)

declare namespace th = "java:net.rootdev.treehugger.TreeHugger";
declare namespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
declare namespace wsdl = "http://schemas.xmlsoap.org/wsdl/";
declare namespace wssoap = "http://schemas.xmlsoap.org/wsdl/soap/";
<results>
   {
      let $doc := th:document('http://www.w3.org/2001/03/19-annotated-RDF-WSDL.rdf')
      for $port in $doc/wsdl:service/wsdl:hasPort/*
      return
         <result>
             <port>{ $port }</port>
             <binding_name>{ $port/wsdl:binding/*/wsdl:hasBinding/*/wssoap:style[@rdf:resource='http://schemas.xmlsoap.org/wsdl/soap/document']/../../../wsdl:name/* }</binding_name>
         </result>
   }
</results>

Functional Accessors

Another syntax using functional accessors: (survey example)

<results>
   {
      let $doc := th:document('http://www.w3.org/2001/03/19-annotated-RDF-WSDL.rdf')
      for $port in $doc/wsdl:service/wsdl:hasPort/*
      return
         <result>
             <port>{ $port }</port>
             <binding_name>{ $port/rdf-navigate-predicate(wsdl:binding)/
		rdf-navigate-object(*)/rdf-navigate-predicate(wsdl:hasBinding)/
		rdf-navigate-object(*)/rdf-navigate-predicate(wssoap:style)
		  [@rdf:resource='http://schemas.xmlsoap.org/wsdl/soap/document']/../../../wsdl:name/* }</binding_name>
         </result>
   }
</results>

Arrow Operator

An example using the Arrow Operator which was tabled to XQuery 2:

<results>
   {
      let $doc := th:document('http://www.w3.org/2001/03/19-annotated-RDF-WSDL.rdf')
      for $port in $doc/wsdl:service/wsdl:hasPort/*
      return
         <result>
             <port>{ $port }</port>
             <binding_name>{ $port=>wsdl:binding=>*=>wsdl:hasBinding=>*=>wssoap:style[@rdf:resource='http://schemas.xmlsoap.org/wsdl/soap/document']/../../../wsdl:name/* }</binding_name>
         </result>
   }
</results>

For Comparison

This alternative was explored and dismissed in Jonathan Robie's The Syntactic Web.

<results>
 {
    LET $t := document("http://www.w3.org/2001/03/19-annotated-RDF-WSDL.rdf")//statement
 
    FOR $service in $t[predicate="rdf:type" and object="wsdl:service"],
        $port in $t[predicate="wsdl:hasPort"], 
        $binding in $t[predicate="wsdl:binding"], 
        $style in $t[predicate="wssoap:style" and object="wssoap:document"], 
        $bindingName in $t[predicate="wsdl:binding"], 
    WHERE $service/subject=$port/subject
      AND $port/object=$binding/subject
      AND $style/subject=$binding/subject
      AND $bindingName/subject=$binding/object
    <description about={$t/text() }>
     {
       for $s in document("sirpac-culture-triples.rdf")//statement
       where $s/subject=$t
       return 
          <{$s/predicate/text()}>
            {
              $s/object/text() 
            } 
          </>
     }
    </description>
 }
</results>