source: pmb4.2/trunk/fuentes/pmb/classes/rdf/arc2/parsers/ARC2_SPOGParser.php @ 815

Last change on this file since 815 was 815, checked in by jrpelegrina, 4 years ago

Initial release of pmb 4.2

  • Property svn:executable set to *
File size: 5.6 KB
Line 
1<?php
2/**
3 * ARC2 streaming SPOG parser
4 *
5 * @author Benjamin Nowack
6 * @license <http://arc.semsol.org/license>
7 * @homepage <http://arc.semsol.org/>
8 * @package ARC2
9 * @version 2010-11-16
10*/
11
12ARC2::inc('RDFParser');
13
14class ARC2_SPOGParser extends ARC2_RDFParser {
15
16  function __construct($a, &$caller) {
17    parent::__construct($a, $caller);
18  }
19 
20  function __init() {/* reader */
21    parent::__init();
22    $this->encoding = $this->v('encoding', false, $this->a);
23    $this->xml = 'http://www.w3.org/XML/1998/namespace';
24    $this->rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
25    $this->nsp = array($this->xml => 'xml', $this->rdf => 'rdf');
26    $this->target_encoding = '';
27  }
28 
29  /*  */
30
31  function parse($path, $data = '', $iso_fallback = false) {
32    $this->state = 0;
33    /* reader */
34    if (!$this->v('reader')) {
35      ARC2::inc('Reader');
36      $this->reader = new ARC2_Reader($this->a, $this);
37    }
38    $this->reader->setAcceptHeader('Accept: sparql-results+xml; q=0.9, */*; q=0.1');
39    $this->reader->activate($path, $data);
40    $this->x_base = isset($this->a['base']) && $this->a['base'] ? $this->a['base'] : $this->reader->base;
41    /* xml parser */
42    $this->initXMLParser();
43    /* parse */
44    $first = true;
45    while ($d = $this->reader->readStream()) {
46      if ($iso_fallback && $first) {
47        $d = '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" . preg_replace('/^\<\?xml [^\>]+\?\>\s*/s', '', $d);
48        $first = false;
49      }
50      if (!xml_parse($this->xml_parser, $d, false)) {
51        $error_str = xml_error_string(xml_get_error_code($this->xml_parser));
52        $line = xml_get_current_line_number($this->xml_parser);
53        $this->tmp_error = 'XML error: "' . $error_str . '" at line ' . $line . ' (parsing as ' . $this->getEncoding() . ')';
54        $this->tmp_error .= $d . urlencode($d);
55        if (0 && !$iso_fallback && preg_match("/Invalid character/i", $error_str)) {
56          xml_parser_free($this->xml_parser);
57          unset($this->xml_parser);
58          $this->reader->closeStream();
59          $this->__init();
60          $this->encoding = 'ISO-8859-1';
61          unset($this->xml_parser);
62          unset($this->reader);
63          return $this->parse($path, $data, true);
64        }
65        else {
66          return $this->addError($this->tmp_error);
67        }
68      }
69    }
70    $this->target_encoding = xml_parser_get_option($this->xml_parser, XML_OPTION_TARGET_ENCODING);
71    xml_parser_free($this->xml_parser);
72    $this->reader->closeStream();
73    unset($this->reader);
74    return $this->done();
75  }
76 
77  /*  */
78 
79  function initXMLParser() {
80    if (!isset($this->xml_parser)) {
81      $enc = preg_match('/^(utf\-8|iso\-8859\-1|us\-ascii)$/i', $this->getEncoding(), $m) ? $m[1] : 'UTF-8';
82      $parser = xml_parser_create($enc);
83      xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
84      xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
85      xml_set_element_handler($parser, 'open', 'close');
86      xml_set_character_data_handler($parser, 'cdata');
87      xml_set_start_namespace_decl_handler($parser, 'nsDecl');
88      xml_set_object($parser, $this);
89      $this->xml_parser = $parser;
90    }
91  }
92
93  /*  */
94 
95  function getEncoding($src = 'config') {
96    if ($src == 'parser') {
97      return $this->target_encoding;
98    }
99    elseif (($src == 'config') && $this->encoding) {
100      return $this->encoding;
101    }
102    return $this->reader->getEncoding();
103    return 'UTF-8';
104  }
105 
106  /*  */
107 
108  function getTriples() {
109    return $this->v('triples', array());
110  }
111 
112  function countTriples() {
113    return $this->t_count;
114  }
115
116  function addT($s = '', $p = '', $o = '', $s_type = '', $o_type = '', $o_dt = '', $o_lang = '', $g = '') {
117    if (!($s && $p && $o)) return 0;
118    //echo "-----\nadding $s / $p / $o\n-----\n";
119    $t = array('s' => $s, 'p' => $p, 'o' => $o, 's_type' => $s_type, 'o_type' => $o_type, 'o_datatype' => $o_dt, 'o_lang' => $o_lang, 'g' => $g);
120    if ($this->skip_dupes) {
121      $h = md5(serialize($t));
122      if (!isset($this->added_triples[$h])) {
123        $this->triples[$this->t_count] = $t;
124        $this->t_count++;
125        $this->added_triples[$h] = true;
126      }
127    }
128    else {
129      $this->triples[$this->t_count] = $t;
130      $this->t_count++;
131    }
132  }
133
134  /*  */
135 
136  function open($p, $t, $a) {
137    $this->state = $t;
138    if ($t == 'result') {
139      $this->t = array();
140    }
141    elseif ($t == 'binding') {
142      $this->binding = $a['name'];
143      $this->t[$this->binding] = '';
144    }
145    elseif ($t == 'literal') {
146      $this->t[$this->binding . '_dt'] = $this->v('datatype', '', $a);
147      $this->t[$this->binding . '_lang'] = $this->v('xml:lang', '', $a);
148      $this->t[$this->binding . '_type'] = 'literal';
149    }
150    elseif ($t == 'uri') {
151      $this->t[$this->binding . '_type'] = 'uri';
152    }
153    elseif ($t == 'bnode') {
154      $this->t[$this->binding . '_type'] = 'bnode';
155      $this->t[$this->binding] = '_:';
156    }
157  }
158 
159  function close($p, $t) {
160    $this->prev_state = $this->state;
161    $this->state = '';
162    if ($t == 'result') {
163      $this->addT(
164        $this->v('s', '', $this->t), 
165        $this->v('p', '', $this->t), 
166        $this->v('o', '', $this->t), 
167        $this->v('s_type', '', $this->t), 
168        $this->v('o_type', '', $this->t), 
169        $this->v('o_dt', '', $this->t), 
170        $this->v('o_lang', '', $this->t), 
171        $this->v('g', '', $this->t)
172      );
173    }
174  }
175
176  function cData($p, $d) {
177    if (in_array($this->state, array('uri', 'bnode', 'literal'))) {
178      $this->t[$this->binding] .= $d;
179    }
180  }
181 
182  function nsDecl($p, $prf, $uri) {
183    $this->nsp[$uri] = isset($this->nsp[$uri]) ? $this->nsp[$uri] : $prf;
184  }
185
186  /*  */
187 
188}
Note: See TracBrowser for help on using the repository browser.