/[drupal]/contributions/modules/sparql/sparql.client.inc
ViewVC logotype

Contents of /contributions/modules/sparql/sparql.client.inc

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.3 - (show annotations) (download) (as text)
Sat Jun 7 20:07:14 2008 UTC (17 months, 2 weeks ago) by arto
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +7 -1 lines
File MIME type: text/x-php
Imported latest 6.x version (r482) from SVN development repository.

Changelog:
- Implemented a proper database schema with a dedicated SQL table, and assorted schema migrations, for SPARQL node data.
- Improved error handling and caching logic for node-based queries.
- Implemented hook_delete() and hook_nodeapi() revision deletion.
- Added more MIME types for SPARQL resultset parsing (they are incorrect, but occasionally encountered in the wild).
- Made specifying the endpoint field mandatory until the Drupal-native engine is ready for prime time.
- Implemented more human-friendly display of query results (requires RDF API 6.x-1.0-alpha2).
- Added note about suppressing the display of previous query results when previewing a changed query.
- Implemented unit tests for querying the CIA Factbook's SPARQL endpoint.
1 <?php
2 // $Id$
3 /**
4 * sparql.client.inc - SPARQL HTTP client implementation.
5 *
6 * @author Arto Bendiken <http://bendiken.net/>
7 * @copyright Copyright (c) 2007-2008 Arto Bendiken. All rights reserved.
8 * @license GPL <http://creativecommons.org/licenses/GPL/2.0/>
9 * @package sparql.module
10 */
11
12 //////////////////////////////////////////////////////////////////////////////
13 // SPARQL HTTP client
14
15 function sparql_request($endpoint, $query, $options = array(), &$errors = NULL) {
16 $options = array_merge(array('query' => $query, 'format' => 'application/sparql-results+json', 'output' => 'json'), $options);
17
18 // HACK
19 if (!isset($options['default-graph-uri']) && preg_match('!dbpedia!', $endpoint)) {
20 $options['default-graph-uri'] = 'http://dbpedia.org';
21 }
22
23 $request = $endpoint . '?' . http_build_query($options, NULL, '&');
24 $headers = array('Accept' => $options['format'] . ', */*');
25 if ($response = drupal_http_request($request, $headers, 'GET')) {
26
27 if (empty($response->code) && empty($response->data)) {
28 $errors[] = t('Remote SPARQL query timed out; please try again.');
29 }
30 else if (isset($response->error) && empty($response->error)) {
31 // This is seen when specifying a URL that doesn't even resolve
32 $errors[] = t('Invalid SPARQL endpoint specified.');
33 }
34 else if (isset($response->error)) {
35 $error = str_replace(SPARQL_Query::prefixes() . "\n", '', $response->data);
36 $errors[] = t('Remote SPARQL endpoint returned error: %error', array('%error' => $error));
37 }
38 else if (preg_match('!^([\w]+/[^;]+)!', $response->headers['Content-Type'], $matches)) {
39
40 switch ($format = $matches[1]) {
41 case 'application/sparql-results+json':
42 case 'application/json':
43 case 'application/javascript':
44 case 'text/javascript':
45 return sparql_parse_json_results($response->data);
46
47 case 'application/sparql-results+xml':
48 case 'application/xml':
49 case 'text/xml':
50 case 'text/plain': // CIA Factbook returns this
51 return sparql_parse_xml_results($response->data);
52
53 default:
54 foreach (rdf_get_formats('info', 'r') as $reader) {
55 if ($reader->mime_type == $format) {
56 if ($result = rdf_unserialize($response->data, array('format' => $reader->name, 'uri' => $endpoint)))
57 return new ArrayIterator($result);
58 break;
59 }
60 }
61 $errors[] = t('Unknown SPARQL results format: %type.', array('%type' => $format));
62 break;
63 }
64 }
65 }
66
67 return NULL;
68 }
69
70 /**
71 * Parses query results in application/sparql-results+json format.
72 *
73 * @see http://www.w3.org/TR/rdf-sparql-json-res/
74 */
75 function sparql_parse_json_results($input) {
76 $input = json_decode($input);
77
78 if (isset($input->boolean)) {
79 return (bool)$input->boolean;
80 }
81
82 $output = $bnodes = array();
83 foreach ($input->results->bindings as $row) {
84 $item = array();
85
86 foreach (get_object_vars($row) as $field => $binding) {
87 switch ($binding->type) {
88 case 'uri':
89 $value = rdf_uriref($binding->value);
90 break;
91 case 'bnode':
92 $bnode_id = $binding->value;
93 $value = isset($bnodes[$bnode_id]) ? $bnodes[$bnode_id] : ($bnodes[$bnode_id] = rdf_bnode());
94 break;
95 case 'literal':
96 $value = isset($binding->{'xml:lang'}) ? rdf_literal($binding->value, $binding->{'xml:lang'}) : $binding->value;
97 break;
98 case 'typed-literal':
99 $value = rdf_literal($binding->value, NULL, rdf_uriref($binding->datatype));
100 break;
101 default: // unknown/invalid
102 continue 2; // skip this binding
103 break;
104 }
105 $item[$field] = $value;
106 }
107
108 $output[] = $item;
109 }
110 return $output;
111 }
112
113 /**
114 * Parses query results in application/sparql-results+xml format.
115 *
116 * @see http://www.w3.org/TR/rdf-sparql-XMLres/
117 */
118 function sparql_parse_xml_results($input) {
119 // FIXME: we seem to have some encoding issues querying against DBpedia.
120 $input = simplexml_load_string($input);
121
122 if (isset($input->boolean)) {
123 return (string)$input->boolean == 'true';
124 }
125
126 $output = $bnodes = array();
127 foreach ($input->results->result as $result) {
128 $item = array();
129
130 foreach ($result->binding as $binding) {
131 if (isset($binding->uri)) {
132 $value = rdf_uriref((string)$binding->uri);
133 }
134 else if (isset($binding->bnode)) {
135 $bnode_id = (string)$binding->bnode;
136 $value = isset($bnodes[$bnode_id]) ? $bnodes[$bnode_id] : ($bnodes[$bnode_id] = rdf_bnode());
137 }
138 else {
139 $literal = $binding->literal;
140 $datatype = isset($literal['datatype']) ? rdf_uriref((string)$literal['datatype']) : NULL;
141 $language = _sparql_parse_xml_results_language($literal);
142 $value = rdf_literal((string)$literal, $language, $datatype);
143 }
144
145 $item[(string)$binding['name']] = $value;
146 }
147
148 $output[] = $item;
149 }
150
151 return $output;
152 }
153
154 function _sparql_parse_xml_results_language($element) {
155 foreach ($element->attributes('http://www.w3.org/XML/1998/namespace') as $name => $value) {
156 if ($name == 'lang') {
157 return (string)$value;
158 }
159 }
160 }

  ViewVC Help
Powered by ViewVC 1.1.2