source: Dev/trunk/rdfapi/sparql/SparqlEngineDb/ResultRenderer/XML.php @ 12

Last change on this file since 12 was 12, checked in by basvannuland, 14 years ago

Added RAP RDF API
Added RDF reader writer for save and load survey

File size: 11.9 KB
Line 
1<?php
2require_once RDFAPI_INCLUDE_DIR . 'sparql/SparqlEngineDb/ResultRenderer.php';
3
4/**
5*   Sparql DB XML result renderer as defined by
6*   http://www.w3.org/TR/rdf-sparql-XMLres/
7*
8*   @author Christian Weiske <cweiske@cweiske.de>
9*   @license http://www.gnu.org/licenses/lgpl.html LGPL
10*
11*   @package sparql
12*/
13class SparqlEngineDb_ResultRenderer_XML implements SparqlEngineDb_ResultRenderer
14{
15
16    /**
17    *   Defines the methods needed to create the types
18    *   in $arVarAssignments.
19    *   Key is the type (e.g. "s" for subject), and
20    *   value the method's name.
21    *
22    *   @see $arVarAssignments
23    *
24    *   @var array
25    */
26    protected $arCreationMethods = array(
27        's' => 'createSubjectFromDbRecordSetPart',
28        'p' => 'createPredicateFromDbRecordSetPart',
29        'o' => 'createObjectFromDbRecordSetPart'
30    );
31
32
33
34    /**
35    *   Converts the database results into nice HTML.
36    *
37    *   @param array $arRecordSets  Array of (possibly several) SQL query results.
38    *   @param Query $query     SPARQL query object
39    *   @param SparqlEngineDb $engine   Sparql Engine to query the database
40    *   @return mixed   HTML code
41    */
42    public function convertFromDbResults($arRecordSets, Query $query, SparqlEngineDb $engine)
43    {
44        $this->query = $query;
45        $this->sg    = $engine->getSqlGenerator();
46        $strCode     = '';
47
48        $strResultForm = $query->getResultForm();
49        switch ($strResultForm) {
50            case 'select':
51            case 'select distinct':
52                $strCode = $this->createFromRecords($arRecordSets, $strResultForm);
53                break;
54
55            case 'construct':
56            case 'describe':
57                throw new Exception(
58                    'Construct and describe are not supported by the'
59                    . ' XML renderer'
60                );
61
62            case 'count':
63            case 'ask':
64                if (count($arRecordSets) > 1) {
65                    throw new Exception(
66                        'More than one result set for a '
67                        . $strResultForm . ' query!'
68                    );
69                }
70
71                $nCount = 0;
72                $dbRecordSet = reset($arRecordSets);
73                foreach ($dbRecordSet as $row) {
74                    $nCount += intval($row['count']);
75                    break;
76                }
77
78                if ($strResultForm == 'ask') {
79                    $strCode = $this->getHead()
80                        . '  <boolean>'
81                        . self::getSpokenBoolean($nCount > 0)
82                        . '</boolean>';
83                } else {
84                    $strCode = $this->getHead()
85                        . '  <int>'
86                        . $nCount
87                        . '</int>';
88                }
89                break;
90
91            default:
92                throw new Exception('Unsupported result form: ' . $strResultForm);
93        }
94
95        return $this->wrapCode($strCode);
96    }//public function convertFromDbResults($arRecordSets, Query $query, SparqlEngineDb $engine)
97
98
99
100    protected function wrapCode($strCode)
101    {
102        return <<<EOT
103<?xml version="1.0"?>
104<sparql xmlns="http://www.w3.org/2005/sparql-results#">
105
106EOT
107            . $strCode . "\n"
108            . "</sparql>\n";
109    }//protected function wrapCode($strCode)
110
111
112
113    protected function getHead($strXml = '')
114    {
115        return "  <head>\n"
116            . $strXml
117            . "  </head>\n";
118    }//protected function getHead($strXml = '')
119
120
121
122    protected function createFromRecords($arRecordSets, $strResultForm)
123    {
124        $arResultVars = $this->query->getResultVars();
125
126        if (in_array('*', $arResultVars)) {
127            $arResultVars   = array_keys($this->sg->arVarAssignments);
128        }
129               
130        $strVarXML = '';
131        foreach ($arResultVars as $var) {
132                $strVarXML .= "    <variable name=\"" . substr((string)$var,1) . "\"/>\n";
133        }
134       
135        $strHeadXml = $this->getHead($strVarXML);
136
137        $arResult = array();
138        foreach ($arRecordSets as $dbRecordSet) {
139            //work around bug in adodb:
140            // ADORecordSet_empty does not implement php5 iterators
141            if ($dbRecordSet->RowCount() <= 0) {
142               
143                return
144                        $strHeadXml
145                        . '  <results ordered="'
146                        . self::getSpokenBoolean($arSM['order by'] !== null)
147                                        . '" distinct="'
148                        . self::getSpokenBoolean($strResultForm == 'select distinct')
149                        . '">' . "\n"
150                        . '    <!-- empty result -->' . PHP_EOL
151                        . "  </results>\n";
152            }
153
154            foreach ($dbRecordSet as $row) {
155                $arResultRow = array();
156                foreach ($arResultVars as $strVar) {
157                    $strVarName = (string)$strVar;
158                    if (!isset($this->sg->arVarAssignments[$strVarName])) {
159                        //variable is in select, but not in result (test: q-select-2)
160                        $arResultRow[$strVarName] = '';
161                    } else {
162                        $arVarSettings  = $this->sg->arVarAssignments[$strVarName];
163                        $strMethod      = $this->arCreationMethods[$arVarSettings[1]];
164                        $arResultRow[$strVarName] = $this->$strMethod($dbRecordSet, $arVarSettings[0], $strVar);
165                    }
166                }
167                $arResult[] = $arResultRow;
168            }
169        }
170
171
172        $arSM = $this->query->getSolutionModifier();
173
174        return
175            $strHeadXml
176            . '  <results ordered="'
177                . self::getSpokenBoolean($arSM['order by'] !== null)
178                . '" distinct="'
179                . self::getSpokenBoolean($strResultForm == 'select distinct')
180                . '">' . "\n"
181            . $this->getResultXml($arResult)
182            . "  </results>\n";
183    }//protected function createFromRecords($arRecordSets)
184
185
186
187    protected function getResultXml($arResult)
188    {
189        $strCode = '';
190        foreach ($arResult as $arSet) {
191            $strCode .= "    <result>\n";
192            foreach ($arSet as $strVarName => $strValue) {
193                if ($strValue !== null) {
194                    $strCode .= '      <binding name="' . substr($strVarName,1) . '">'
195                        . $strValue
196                        . "</binding>\n";
197                }
198            }
199            $strCode .= "    </result>\n";
200        }
201        return $strCode;
202    }//protected function getResultXml($arResult)
203
204
205
206    protected static function getSpokenBoolean($b)
207    {
208        return $b ? 'true' : 'false';
209    }//protected static function getSpokenBoolean($b)
210
211
212
213    /**
214    *   Creates an RDF subject object
215    *   contained in the given $dbRecordSet object.
216    *
217    *   @see convertFromDbResult() to understand $strVarBase necessity
218    *
219    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
220    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
221    *
222    *   @return string HTML code
223    */
224    protected function createSubjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
225    {
226        $strVarName = (string)$strVar;
227        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
228            return $this->getXmlNull();
229        }
230        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']] == 'r'
231            //null should be predicate which is always a resource
232         || $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']] === null
233        ) {
234            return $this->getXmlResource($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
235        } else {
236            return $this->getXmlBlank($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
237        }
238    }//protected function createSubjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
239
240
241
242    /**
243    *   Creates an RDF predicate object
244    *   contained in the given $dbRecordSet object.
245    *
246    *   @see convertFromDbResult() to understand $strVarBase necessity
247    *
248    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
249    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
250    *
251    *   @return string HTML code
252    */
253    protected function createPredicateFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
254    {
255        $strVarName = (string)$strVar;
256        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
257            return $this->getXmlNull();
258        }
259
260        return $this->getXmlResource($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
261    }//protected function createPredicateFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
262
263
264
265    /**
266    *   Creates an RDF object object
267    *   contained in the given $dbRecordSet object.
268    *
269    *   @see convertFromDbResult() to understand $strVarBase necessity
270    *
271    *   @param ADORecordSet $dbRecordSet    Record set returned from ADOConnection::Execute()
272    *   @param string       $strVarBase     Prefix of the columns the recordset fields have.
273    *
274    *   @return string HTML code
275    */
276    protected function createObjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
277    {
278        $strVarName = (string)$strVar;
279        if ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']] === null) {
280            return $this->getXmlNull();
281        }
282        switch ($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_is']]) {
283            case 'r':
284                return $this->getXmlResource($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
285                break;
286            case 'b':
287                return $this->getXmlBlank($dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']]);
288                break;
289            default:
290                return $this->getXmlLiteral(
291                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_value']],
292                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_lang']],
293                    $dbRecordSet->fields[$strVarBase . '.' . $this->sg->arVarAssignments[$strVarName]['sql_type']]
294                );
295        }
296    }//protected function createObjectFromDbRecordSetPart(ADORecordSet $dbRecordSet, $strVarBase, $strVar)
297
298
299
300    protected function getXmlNull()
301    {
302        return null;
303    }//protected function getHtmlNull()
304
305
306
307    protected function getXmlBlank($value)
308    {
309        return '<bnode>' . $value . '</bnode>';
310    }//protected function getHtmlBlank($value)
311
312
313
314    protected function getXmlResource($value)
315    {
316        return '<uri>' . htmlspecialchars($value) . '</uri>';
317    }//protected function getHtmlResource($value)
318
319
320
321    protected function getXmlLiteral($value, $language, $datatype)
322    {
323        $strCode = '<literal';
324        if ($language) {
325            $strCode . ' xml:lang="' . $language . '"';
326        }
327        if ($datatype) {
328            $strCode . ' datatype="' . $datatype . '"';
329        }
330        $strCode .= '>' . htmlspecialchars($value) . '</literal>';
331        return $strCode;
332    }//protected function getHtmlLiteral($value, $language, $datatype)
333
334}//class SparqlEngineDb_ResultRenderer_XML implements SparqlEngineDb_ResultRenderer
335
336?>
Note: See TracBrowser for help on using the repository browser.