domenica 13 novembre 2011

Esempi SPARQL e php

While the code may look complex at first blush, it is actually a straightforward tool.

We will begin by taking a quick glance at the first dozen lines:

  // URL to DB Pedia's SPARQL endpoint.
  $url = 'http://dbpedia.org/sparql';

  // The SPARQL query to run.
  $sparql = '
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    SELECT ?uri ?name ?label
    WHERE {
      ?uri foaf:name ?name .
      ?uri rdfs:label ?label
      FILTER (?name = "The Beatles")
      FILTER (lang(?label) = "en")
    }
  ';

  // We first set up the parameters that will be sent.
  $params = array(
    'query' => $sparql,
    'format' => 'application/sparql-results+xml',
  );

  // DB Pedia wants a GET query, so we create one.
  $data = http_build_query($params);
  $url .= '?' . $data;


The snippet above shows all of the preparation we must make to run the query.

We begin with a base $url, which points to the DBPedia SPARQL endpoint. Next we write our SPARQL query. The query above is the same as the one we saw earlier in this article.

With the query and the base URL, we need to build a full URL to access the remote server. This is done with the $params array. There we create the name/value pairs that will be condensed into a GET string by http_build_query(). Note that we set the MIME type as the value of the $params['format'] entry. This is to tell the remote server what kind of data we expect to have returned.

A SPARQL query need not return information encoded as XML. Other data formats are equally capable of representing SPARQL query results. XML is probably the most widely used, though, and is the easiest for us to parse.

In the last line of the snippet above, we assemble our base URL and query params into a complete URL.

Next, we need to execute the query and handle the results.

<?php
  // Next, we simply retrieve, parse, and output the contents.
  $qp = qp($url, 'head');

  // Get the headers from the resulting XML.
  $headers = array();
  foreach ($qp->children('variable') as $col) {
    $headers[] = $col->attr('name');
  }

  // Get rows of data from result.
  $rows = array();
  $col_count = count($headers);
  foreach ($qp->top()->find('results>result') as $row) {
    $cols = array();
    $row->children();
    for ($i = 0; $i < $col_count; ++$i) {
      $cols[$i] = $row->branch()->eq($i)->text();
    }
    $rows[] = $cols;
  }
?>

We begin by creating a new QueryPath object, stored in $qp. Based on the CSS query, we can see that it will be pointed to the header element in the returned results. This element will contain the names of each of the returned variables of data.

From there, we build an array of $headers, getting the name of each returned variable. These we will use to generate the headers in our table. The headers come back in variable elements, and each variable has a name attribute. To fetch them, then, we select the variables and loop through them, retrieving the name attribute of each.

Next comes the fancy part. We need to loop through each result and fetch each variable out of each result. Or, to use the table metaphor we SQL developers are familiar with, we loop through each row, and fetch each column of data. This is al accomplished in the this foreach loop:

foreach ($qp->top()->find('results>result') as $row) {
  $cols = array();
  $row->children();
  for ($i = 0; $i < $col_count; ++$i) {
    $cols[$i] = $row->branch()->eq($i)->text();
  }
  $rows[] = $cols;


When this loop is finished, there will be an array of rows, each of which will have an array of columns. The index of the columns should match the index of the headers array. That is how we correlate headers to columns. You may also notice that we use QueryPath's 'branch() method in combination with eq() so that we can (relatively cheaply) get the text for each column.

With this complete, the next thing to do is format the table output:

Nessun commento:

Posta un commento