Mercurial > hg > rr-repo
comparison sites/all/libraries/ARC2/arc/parsers/ARC2_RDFXMLParser.php @ 4:ce11bbd8f642
added modules
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Thu, 19 Sep 2013 10:38:44 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:b28be78d8160 | 4:ce11bbd8f642 |
---|---|
1 <?php | |
2 /** | |
3 * ARC2 RDF/XML Parser | |
4 * | |
5 * @author Benjamin Nowack <bnowack@semsol.com> | |
6 * @license http://arc.semsol.org/license | |
7 * @homepage <http://arc.semsol.org/> | |
8 * @package ARC2 | |
9 */ | |
10 | |
11 ARC2::inc('RDFParser'); | |
12 | |
13 class ARC2_RDFXMLParser extends ARC2_RDFParser { | |
14 | |
15 function __construct($a, &$caller) { | |
16 parent::__construct($a, $caller); | |
17 } | |
18 | |
19 function __init() {/* reader */ | |
20 parent::__init(); | |
21 $this->encoding = $this->v('encoding', false, $this->a); | |
22 $this->state = 0; | |
23 $this->x_lang = ''; | |
24 $this->x_base = $this->base; | |
25 $this->xml = 'http://www.w3.org/XML/1998/namespace'; | |
26 $this->rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'; | |
27 $this->nsp = array($this->xml => 'xml', $this->rdf => 'rdf'); | |
28 $this->s_stack = array(); | |
29 $this->s_count = 0; | |
30 $this->target_encoding = ''; | |
31 } | |
32 | |
33 /* */ | |
34 | |
35 function parse($path, $data = '', $iso_fallback = false) { | |
36 /* reader */ | |
37 if (!$this->v('reader')) { | |
38 ARC2::inc('Reader'); | |
39 $this->reader = new ARC2_Reader($this->a, $this); | |
40 } | |
41 $this->reader->setAcceptHeader('Accept: application/rdf+xml; q=0.9, */*; q=0.1'); | |
42 $this->reader->activate($path, $data); | |
43 $this->x_base = isset($this->a['base']) && $this->a['base'] ? $this->a['base'] : $this->reader->base; | |
44 /* xml parser */ | |
45 $this->initXMLParser(); | |
46 /* parse */ | |
47 $first = true; | |
48 while ($d = $this->reader->readStream()) { | |
49 if (!$this->keep_time_limit) @set_time_limit($this->v('time_limit', 60, $this->a)); | |
50 if ($iso_fallback && $first) { | |
51 $d = '<?xml version="1.0" encoding="ISO-8859-1"?>' . "\n" . preg_replace('/^\<\?xml [^\>]+\?\>\s*/s', '', $d); | |
52 $first = false; | |
53 } | |
54 if (!xml_parse($this->xml_parser, $d, false)) { | |
55 $error_str = xml_error_string(xml_get_error_code($this->xml_parser)); | |
56 $line = xml_get_current_line_number($this->xml_parser); | |
57 $this->tmp_error = 'XML error: "' . $error_str . '" at line ' . $line . ' (parsing as ' . $this->getEncoding() . ')'; | |
58 if (!$iso_fallback && preg_match("/Invalid character/i", $error_str)) { | |
59 xml_parser_free($this->xml_parser); | |
60 unset($this->xml_parser); | |
61 $this->reader->closeStream(); | |
62 $this->__init(); | |
63 $this->encoding = 'ISO-8859-1'; | |
64 unset($this->xml_parser); | |
65 unset($this->reader); | |
66 return $this->parse($path, $data, true); | |
67 } | |
68 else { | |
69 return $this->addError($this->tmp_error); | |
70 } | |
71 } | |
72 } | |
73 $this->target_encoding = xml_parser_get_option($this->xml_parser, XML_OPTION_TARGET_ENCODING); | |
74 xml_parser_free($this->xml_parser); | |
75 $this->reader->closeStream(); | |
76 unset($this->reader); | |
77 return $this->done(); | |
78 } | |
79 | |
80 /* */ | |
81 | |
82 function initXMLParser() { | |
83 if (!isset($this->xml_parser)) { | |
84 $enc = preg_match('/^(utf\-8|iso\-8859\-1|us\-ascii)$/i', $this->getEncoding(), $m) ? $m[1] : 'UTF-8'; | |
85 $parser = xml_parser_create_ns($enc, ''); | |
86 xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0); | |
87 xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); | |
88 xml_set_element_handler($parser, 'open', 'close'); | |
89 xml_set_character_data_handler($parser, 'cdata'); | |
90 xml_set_start_namespace_decl_handler($parser, 'nsDecl'); | |
91 xml_set_object($parser, $this); | |
92 $this->xml_parser = $parser; | |
93 } | |
94 } | |
95 | |
96 /* */ | |
97 | |
98 function getEncoding($src = 'config') { | |
99 if ($src == 'parser') { | |
100 return $this->target_encoding; | |
101 } | |
102 elseif (($src == 'config') && $this->encoding) { | |
103 return $this->encoding; | |
104 } | |
105 return $this->reader->getEncoding(); | |
106 } | |
107 | |
108 /* */ | |
109 | |
110 function getTriples() { | |
111 return $this->v('triples', array()); | |
112 } | |
113 | |
114 function countTriples() { | |
115 return $this->t_count; | |
116 } | |
117 | |
118 /* */ | |
119 | |
120 function pushS(&$s) { | |
121 $s['pos'] = $this->s_count; | |
122 $this->s_stack[$this->s_count] = $s; | |
123 $this->s_count++; | |
124 } | |
125 | |
126 function popS(){/* php 4.0.x-safe */ | |
127 $r = array(); | |
128 $this->s_count--; | |
129 for ($i = 0, $i_max = $this->s_count; $i < $i_max; $i++) { | |
130 $r[$i] = $this->s_stack[$i]; | |
131 } | |
132 $this->s_stack = $r; | |
133 } | |
134 | |
135 function updateS($s) { | |
136 $this->s_stack[$s['pos']] = $s; | |
137 } | |
138 | |
139 function getParentS() { | |
140 return ($this->s_count && isset($this->s_stack[$this->s_count - 1])) ? $this->s_stack[$this->s_count - 1] : false; | |
141 } | |
142 | |
143 function getParentXBase() { | |
144 if ($p = $this->getParentS()) { | |
145 return isset($p['p_x_base']) && $p['p_x_base'] ? $p['p_x_base'] : (isset($p['x_base']) ? $p['x_base'] : ''); | |
146 } | |
147 return $this->x_base; | |
148 } | |
149 | |
150 function getParentXLang() { | |
151 if ($p = $this->getParentS()) { | |
152 return isset($p['p_x_lang']) && $p['p_x_lang'] ? $p['p_x_lang'] : (isset($p['x_lang']) ? $p['x_lang'] : ''); | |
153 } | |
154 return $this->x_lang; | |
155 } | |
156 | |
157 /* */ | |
158 | |
159 function addT($s, $p, $o, $s_type, $o_type, $o_dt = '', $o_lang = '') { | |
160 //echo "-----\nadding $s / $p / $o\n-----\n"; | |
161 $t = array('s' => $s, 'p' => $p, 'o' => $o, 's_type' => $s_type, 'o_type' => $o_type, 'o_datatype' => $o_dt, 'o_lang' => $o_lang); | |
162 if ($this->skip_dupes) { | |
163 $h = md5(serialize($t)); | |
164 if (!isset($this->added_triples[$h])) { | |
165 $this->triples[$this->t_count] = $t; | |
166 $this->t_count++; | |
167 $this->added_triples[$h] = true; | |
168 } | |
169 } | |
170 else { | |
171 $this->triples[$this->t_count] = $t; | |
172 $this->t_count++; | |
173 } | |
174 } | |
175 | |
176 function reify($t, $s, $p, $o, $s_type, $o_type, $o_dt = '', $o_lang = '') { | |
177 $this->addT($t, $this->rdf.'type', $this->rdf.'Statement', 'uri', 'uri'); | |
178 $this->addT($t, $this->rdf.'subject', $s, 'uri', $s_type); | |
179 $this->addT($t, $this->rdf.'predicate', $p, 'uri', 'uri'); | |
180 $this->addT($t, $this->rdf.'object', $o, 'uri', $o_type, $o_dt, $o_lang); | |
181 } | |
182 | |
183 /* */ | |
184 | |
185 function open($p, $t, $a) { | |
186 //echo "state is $this->state\n"; | |
187 //echo "opening $t\n"; | |
188 switch($this->state) { | |
189 case 0: return $this->h0Open($t, $a); | |
190 case 1: return $this->h1Open($t, $a); | |
191 case 2: return $this->h2Open($t, $a); | |
192 case 4: return $this->h4Open($t, $a); | |
193 case 5: return $this->h5Open($t, $a); | |
194 case 6: return $this->h6Open($t, $a); | |
195 default: $this->addError('open() called at state ' . $this->state . ' in '.$t); | |
196 } | |
197 } | |
198 | |
199 function close($p, $t) { | |
200 //echo "state is $this->state\n"; | |
201 //echo "closing $t\n"; | |
202 switch($this->state){ | |
203 case 1: return $this->h1Close($t); | |
204 case 2: return $this->h2Close($t); | |
205 case 3: return $this->h3Close($t); | |
206 case 4: return $this->h4Close($t); | |
207 case 5: return $this->h5Close($t); | |
208 case 6: return $this->h6Close($t); | |
209 default: $this->addError('close() called at state ' . $this->state . ' in '.$t); | |
210 } | |
211 } | |
212 | |
213 function cdata($p, $d) { | |
214 //echo "state is $this->state\n"; | |
215 //echo "cdata\n"; | |
216 switch($this->state){ | |
217 case 4: return $this->h4Cdata($d); | |
218 case 6: return $this->h6Cdata($d); | |
219 default: return false; | |
220 } | |
221 } | |
222 | |
223 function nsDecl($p, $prf, $uri) { | |
224 $this->nsp[$uri] = isset($this->nsp[$uri]) ? $this->nsp[$uri] : $prf; | |
225 } | |
226 | |
227 /* */ | |
228 | |
229 function h0Open($t, $a) { | |
230 $this->x_lang = $this->v($this->xml.'lang', $this->x_lang, $a); | |
231 $this->x_base = $this->calcURI($this->v($this->xml.'base', $this->x_base, $a)); | |
232 $this->state = 1; | |
233 if ($t !== $this->rdf.'RDF') { | |
234 $this->h1Open($t, $a); | |
235 } | |
236 } | |
237 | |
238 /* */ | |
239 | |
240 function h1Open($t, $a) { | |
241 $s = array( | |
242 'x_base' => isset($a[$this->xml.'base']) ? $this->calcURI($a[$this->xml.'base']) : $this->getParentXBase(), | |
243 'x_lang' => isset($a[$this->xml.'lang']) ? $a[$this->xml.'lang'] : $this->getParentXLang(), | |
244 'li_count' => 0, | |
245 ); | |
246 /* ID */ | |
247 if (isset($a[$this->rdf.'ID'])) { | |
248 $s['type'] = 'uri'; | |
249 $s['value'] = $this->calcURI('#'.$a[$this->rdf.'ID'], $s['x_base']); | |
250 } | |
251 /* about */ | |
252 elseif (isset($a[$this->rdf.'about'])) { | |
253 $s['type'] = 'uri'; | |
254 $s['value'] = $this->calcURI($a[$this->rdf.'about'], $s['x_base']); | |
255 } | |
256 /* bnode */ | |
257 else { | |
258 $s['type'] = 'bnode'; | |
259 if (isset($a[$this->rdf.'nodeID'])) { | |
260 $s['value'] = '_:'.$a[$this->rdf.'nodeID']; | |
261 } | |
262 else { | |
263 $s['value'] = $this->createBnodeID(); | |
264 } | |
265 } | |
266 /* sub-node */ | |
267 if ($this->state === 4) { | |
268 $sup_s = $this->getParentS(); | |
269 /* new collection */ | |
270 if (isset($sup_s['o_is_coll']) && $sup_s['o_is_coll']) { | |
271 $coll = array('value' => $this->createBnodeID(), 'type' => 'bnode', 'is_coll' => true, 'x_base' => $s['x_base'], 'x_lang' => $s['x_lang']); | |
272 $this->addT($sup_s['value'], $sup_s['p'], $coll['value'], $sup_s['type'], $coll['type']); | |
273 $this->addT($coll['value'], $this->rdf . 'first', $s['value'], $coll['type'], $s['type']); | |
274 $this->pushS($coll); | |
275 } | |
276 /* new entry in existing coll */ | |
277 elseif (isset($sup_s['is_coll']) && $sup_s['is_coll']) { | |
278 $coll = array('value' => $this->createBnodeID(), 'type' => 'bnode', 'is_coll' => true, 'x_base' => $s['x_base'], 'x_lang' => $s['x_lang']); | |
279 $this->addT($sup_s['value'], $this->rdf . 'rest', $coll['value'], $sup_s['type'], $coll['type']); | |
280 $this->addT($coll['value'], $this->rdf . 'first', $s['value'], $coll['type'], $s['type']); | |
281 $this->pushS($coll); | |
282 } | |
283 /* normal sub-node */ | |
284 elseif(isset($sup_s['p']) && $sup_s['p']) { | |
285 $this->addT($sup_s['value'], $sup_s['p'], $s['value'], $sup_s['type'], $s['type']); | |
286 } | |
287 } | |
288 /* typed node */ | |
289 if ($t !== $this->rdf.'Description') { | |
290 $this->addT($s['value'], $this->rdf.'type', $t, $s['type'], 'uri'); | |
291 } | |
292 /* (additional) typing attr */ | |
293 if (isset($a[$this->rdf.'type'])) { | |
294 $this->addT($s['value'], $this->rdf.'type', $a[$this->rdf.'type'], $s['type'], 'uri'); | |
295 } | |
296 /* Seq|Bag|Alt */ | |
297 if (in_array($t, array($this->rdf.'Seq', $this->rdf.'Bag', $this->rdf.'Alt'))) { | |
298 $s['is_con'] = true; | |
299 } | |
300 /* any other attrs (skip rdf and xml, except rdf:_, rdf:value, rdf:Seq) */ | |
301 foreach($a as $k => $v) { | |
302 if (((strpos($k, $this->xml) === false) && (strpos($k, $this->rdf) === false)) || preg_match('/(\_[0-9]+|value|Seq|Bag|Alt|Statement|Property|List)$/', $k)) { | |
303 if (strpos($k, ':')) { | |
304 $this->addT($s['value'], $k, $v, $s['type'], 'literal', '', $s['x_lang']); | |
305 } | |
306 } | |
307 } | |
308 $this->pushS($s); | |
309 $this->state = 2; | |
310 } | |
311 | |
312 /* */ | |
313 | |
314 function h2Open($t, $a) { | |
315 $s = $this->getParentS(); | |
316 foreach (array('p_x_base', 'p_x_lang', 'p_id', 'o_is_coll') as $k) { | |
317 unset($s[$k]); | |
318 } | |
319 /* base */ | |
320 if (isset($a[$this->xml.'base'])) { | |
321 $s['p_x_base'] = $this->calcURI($a[$this->xml.'base'], $s['x_base']); | |
322 } | |
323 $b = isset($s['p_x_base']) && $s['p_x_base'] ? $s['p_x_base'] : $s['x_base']; | |
324 /* lang */ | |
325 if (isset($a[$this->xml.'lang'])) { | |
326 $s['p_x_lang'] = $a[$this->xml.'lang']; | |
327 } | |
328 $l = isset($s['p_x_lang']) && $s['p_x_lang'] ? $s['p_x_lang'] : $s['x_lang']; | |
329 /* adjust li */ | |
330 if ($t === $this->rdf.'li') { | |
331 $s['li_count']++; | |
332 $t = $this->rdf.'_'.$s['li_count']; | |
333 } | |
334 /* set p */ | |
335 $s['p'] = $t; | |
336 /* reification */ | |
337 if (isset($a[$this->rdf.'ID'])) { | |
338 $s['p_id'] = $a[$this->rdf.'ID']; | |
339 } | |
340 $o = array('value' => '', 'type' => '', 'x_base' => $b, 'x_lang' => $l); | |
341 /* resource/rdf:resource */ | |
342 if (isset($a['resource'])) { | |
343 $a[$this->rdf . 'resource'] = $a['resource']; | |
344 unset($a['resource']); | |
345 } | |
346 if (isset($a[$this->rdf.'resource'])) { | |
347 $o['value'] = $this->calcURI($a[$this->rdf.'resource'], $b); | |
348 $o['type'] = 'uri'; | |
349 $this->addT($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
350 /* type */ | |
351 if (isset($a[$this->rdf.'type'])) { | |
352 $this->addT($o['value'], $this->rdf.'type', $a[$this->rdf.'type'], 'uri', 'uri'); | |
353 } | |
354 /* reification */ | |
355 if (isset($s['p_id'])) { | |
356 $this->reify($this->calcURI('#'.$s['p_id'], $b), $s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
357 unset($s['p_id']); | |
358 } | |
359 $this->state = 3; | |
360 } | |
361 /* named bnode */ | |
362 elseif (isset($a[$this->rdf.'nodeID'])) { | |
363 $o['value'] = '_:' . $a[$this->rdf.'nodeID']; | |
364 $o['type'] = 'bnode'; | |
365 $this->addT($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
366 $this->state = 3; | |
367 /* reification */ | |
368 if (isset($s['p_id'])) { | |
369 $this->reify($this->calcURI('#'.$s['p_id'], $b), $s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
370 } | |
371 } | |
372 /* parseType */ | |
373 elseif (isset($a[$this->rdf.'parseType'])) { | |
374 if ($a[$this->rdf.'parseType'] === 'Literal') { | |
375 $s['o_xml_level'] = 0; | |
376 $s['o_xml_data'] = ''; | |
377 $s['p_xml_literal_level'] = 0; | |
378 $s['ns'] = array(); | |
379 $this->state = 6; | |
380 } | |
381 elseif ($a[$this->rdf.'parseType'] === 'Resource') { | |
382 $o['value'] = $this->createBnodeID(); | |
383 $o['type'] = 'bnode'; | |
384 $o['has_closing_tag'] = 0; | |
385 $this->addT($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
386 $this->pushS($o); | |
387 /* reification */ | |
388 if (isset($s['p_id'])) { | |
389 $this->reify($this->calcURI('#'.$s['p_id'], $b), $s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
390 unset($s['p_id']); | |
391 } | |
392 $this->state = 2; | |
393 } | |
394 elseif ($a[$this->rdf.'parseType'] === 'Collection') { | |
395 $s['o_is_coll'] = true; | |
396 $this->state = 4; | |
397 } | |
398 } | |
399 /* sub-node or literal */ | |
400 else { | |
401 $s['o_cdata'] = ''; | |
402 if (isset($a[$this->rdf.'datatype'])) { | |
403 $s['o_datatype'] = $a[$this->rdf.'datatype']; | |
404 } | |
405 $this->state = 4; | |
406 } | |
407 /* any other attrs (skip rdf and xml) */ | |
408 foreach($a as $k => $v) { | |
409 if (((strpos($k, $this->xml) === false) && (strpos($k, $this->rdf) === false)) || preg_match('/(\_[0-9]+|value)$/', $k)) { | |
410 if (strpos($k, ':')) { | |
411 if (!$o['value']) { | |
412 $o['value'] = $this->createBnodeID(); | |
413 $o['type'] = 'bnode'; | |
414 $this->addT($s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
415 } | |
416 /* reification */ | |
417 if (isset($s['p_id'])) { | |
418 $this->reify($this->calcURI('#'.$s['p_id'], $b), $s['value'], $s['p'], $o['value'], $s['type'], $o['type']); | |
419 unset($s['p_id']); | |
420 } | |
421 $this->addT($o['value'], $k, $v, $o['type'], 'literal'); | |
422 $this->state = 3; | |
423 } | |
424 } | |
425 } | |
426 $this->updateS($s); | |
427 } | |
428 | |
429 /* */ | |
430 | |
431 function h4Open($t, $a) { | |
432 return $this->h1Open($t, $a); | |
433 } | |
434 | |
435 /* */ | |
436 | |
437 function h5Open($t, $a) { | |
438 $this->state = 4; | |
439 return $this->h4Open($t, $a); | |
440 } | |
441 | |
442 /* */ | |
443 | |
444 function h6Open($t, $a) { | |
445 $s = $this->getParentS(); | |
446 $data = isset($s['o_xml_data']) ? $s['o_xml_data'] : ''; | |
447 $ns = isset($s['ns']) ? $s['ns'] : array(); | |
448 $parts = $this->splitURI($t); | |
449 if ((count($parts) === 1) || empty($parts[1])) { | |
450 $data .= '<'.$t; | |
451 } | |
452 else { | |
453 $ns_uri = $parts[0]; | |
454 $name = $parts[1]; | |
455 if (!isset($this->nsp[$ns_uri])) { | |
456 foreach ($this->nsp as $tmp1 => $tmp2) { | |
457 if (strpos($t, $tmp1) === 0) { | |
458 $ns_uri = $tmp1; | |
459 $name = substr($t, strlen($tmp1)); | |
460 break; | |
461 } | |
462 } | |
463 } | |
464 $nsp = $this->nsp[$ns_uri]; | |
465 $data .= $nsp ? '<' . $nsp . ':' . $name : '<' . $name; | |
466 /* ns */ | |
467 if (!isset($ns[$nsp.'='.$ns_uri]) || !$ns[$nsp.'='.$ns_uri]) { | |
468 $data .= $nsp ? ' xmlns:'.$nsp.'="'.$ns_uri.'"' : ' xmlns="'.$ns_uri.'"'; | |
469 $ns[$nsp.'='.$ns_uri] = true; | |
470 $s['ns'] = $ns; | |
471 } | |
472 } | |
473 foreach ($a as $k => $v) { | |
474 $parts = $this->splitURI($k); | |
475 if (count($parts) === 1) { | |
476 $data .= ' '.$k.'="'.$v.'"'; | |
477 } | |
478 else { | |
479 $ns_uri = $parts[0]; | |
480 $name = $parts[1]; | |
481 $nsp = $this->v($ns_uri, '', $this->nsp); | |
482 $data .= $nsp ? ' '.$nsp.':'.$name.'="'.$v.'"' : ' '.$name.'="'.$v.'"' ; | |
483 } | |
484 } | |
485 $data .= '>'; | |
486 $s['o_xml_data'] = $data; | |
487 $s['o_xml_level'] = isset($s['o_xml_level']) ? $s['o_xml_level'] + 1 : 1; | |
488 if ($t == $s['p']) {/* xml container prop */ | |
489 $s['p_xml_literal_level'] = isset($s['p_xml_literal_level']) ? $s['p_xml_literal_level'] + 1 : 1; | |
490 } | |
491 $this->updateS($s); | |
492 } | |
493 | |
494 /* */ | |
495 | |
496 function h1Close($t) {/* end of doc */ | |
497 $this->state = 0; | |
498 } | |
499 | |
500 /* */ | |
501 | |
502 function h2Close($t) {/* expecting a prop, getting a close */ | |
503 if ($s = $this->getParentS()) { | |
504 $has_closing_tag = (isset($s['has_closing_tag']) && !$s['has_closing_tag']) ? 0 : 1; | |
505 $this->popS(); | |
506 $this->state = 5; | |
507 if ($s = $this->getParentS()) {/* new s */ | |
508 if (!isset($s['p']) || !$s['p']) {/* p close after collection|parseType=Resource|node close after p close */ | |
509 $this->state = $this->s_count ? 4 : 1; | |
510 if (!$has_closing_tag) { | |
511 $this->state = 2; | |
512 } | |
513 } | |
514 elseif (!$has_closing_tag) { | |
515 $this->state = 2; | |
516 } | |
517 } | |
518 } | |
519 } | |
520 | |
521 /* */ | |
522 | |
523 function h3Close($t) {/* p close */ | |
524 $this->state = 2; | |
525 } | |
526 | |
527 /* */ | |
528 | |
529 function h4Close($t) {/* empty p | pClose after cdata | pClose after collection */ | |
530 if ($s = $this->getParentS()) { | |
531 $b = isset($s['p_x_base']) && $s['p_x_base'] ? $s['p_x_base'] : (isset($s['x_base']) ? $s['x_base'] : ''); | |
532 if (isset($s['is_coll']) && $s['is_coll']) { | |
533 $this->addT($s['value'], $this->rdf . 'rest', $this->rdf . 'nil', $s['type'], 'uri'); | |
534 /* back to collection start */ | |
535 while ((!isset($s['p']) || ($s['p'] != $t))) { | |
536 $sub_s = $s; | |
537 $this->popS(); | |
538 $s = $this->getParentS(); | |
539 } | |
540 /* reification */ | |
541 if (isset($s['p_id']) && $s['p_id']) { | |
542 $this->reify($this->calcURI('#'.$s['p_id'], $b), $s['value'], $s['p'], $sub_s['value'], $s['type'], $sub_s['type']); | |
543 } | |
544 unset($s['p']); | |
545 $this->updateS($s); | |
546 } | |
547 else { | |
548 $dt = isset($s['o_datatype']) ? $s['o_datatype'] : ''; | |
549 $l = isset($s['p_x_lang']) && $s['p_x_lang'] ? $s['p_x_lang'] : (isset($s['x_lang']) ? $s['x_lang'] : ''); | |
550 $o = array('type' => 'literal', 'value' => $s['o_cdata']); | |
551 $this->addT($s['value'], $s['p'], $o['value'], $s['type'], $o['type'], $dt, $l); | |
552 /* reification */ | |
553 if (isset($s['p_id']) && $s['p_id']) { | |
554 $this->reify($this->calcURI('#'.$s['p_id'], $b), $s['value'], $s['p'], $o['value'], $s['type'], $o['type'], $dt, $l); | |
555 } | |
556 unset($s['o_cdata']); | |
557 unset($s['o_datatype']); | |
558 unset($s['p']); | |
559 $this->updateS($s); | |
560 } | |
561 $this->state = 2; | |
562 } | |
563 } | |
564 | |
565 /* */ | |
566 | |
567 function h5Close($t) {/* p close */ | |
568 if ($s = $this->getParentS()) { | |
569 unset($s['p']); | |
570 $this->updateS($s); | |
571 $this->state = 2; | |
572 } | |
573 } | |
574 | |
575 /* */ | |
576 | |
577 function h6Close($t) { | |
578 if ($s = $this->getParentS()) { | |
579 $l = isset($s['p_x_lang']) && $s['p_x_lang'] ? $s['p_x_lang'] : (isset($s['x_lang']) ? $s['x_lang'] : ''); | |
580 $data = $s['o_xml_data']; | |
581 $level = $s['o_xml_level']; | |
582 if ($level === 0) {/* pClose */ | |
583 $this->addT($s['value'], $s['p'], trim($data, ' '), $s['type'], 'literal', $this->rdf.'XMLLiteral', $l); | |
584 unset($s['o_xml_data']); | |
585 $this->state = 2; | |
586 } | |
587 else { | |
588 $parts = $this->splitURI($t); | |
589 if ((count($parts) === 1) || empty($parts[1])) { | |
590 $data .= '</'.$t.'>'; | |
591 } | |
592 else { | |
593 $ns_uri = $parts[0]; | |
594 $name = $parts[1]; | |
595 if (!isset($this->nsp[$ns_uri])) { | |
596 foreach ($this->nsp as $tmp1 => $tmp2) { | |
597 if (strpos($t, $tmp1) === 0) { | |
598 $ns_uri = $tmp1; | |
599 $name = substr($t, strlen($tmp1)); | |
600 break; | |
601 } | |
602 } | |
603 } | |
604 $nsp = $this->nsp[$ns_uri]; | |
605 $data .= $nsp ? '</'.$nsp.':'.$name.'>' : '</'.$name.'>'; | |
606 } | |
607 $s['o_xml_data'] = $data; | |
608 $s['o_xml_level'] = $level - 1; | |
609 if ($t == $s['p']) {/* xml container prop */ | |
610 $s['p_xml_literal_level']--; | |
611 } | |
612 } | |
613 $this->updateS($s); | |
614 } | |
615 } | |
616 | |
617 /* */ | |
618 | |
619 function h4Cdata($d) { | |
620 if ($s = $this->getParentS()) { | |
621 $s['o_cdata'] = isset($s['o_cdata']) ? $s['o_cdata'] . $d : $d; | |
622 $this->updateS($s); | |
623 } | |
624 } | |
625 | |
626 /* */ | |
627 | |
628 function h6Cdata($d) { | |
629 if ($s = $this->getParentS()) { | |
630 if (isset($s['o_xml_data']) || preg_match("/[\n\r]/", $d) || trim($d)) { | |
631 $d = htmlspecialchars($d, ENT_NOQUOTES); | |
632 $s['o_xml_data'] = isset($s['o_xml_data']) ? $s['o_xml_data'] . $d : $d; | |
633 } | |
634 $this->updateS($s); | |
635 } | |
636 } | |
637 | |
638 /* */ | |
639 | |
640 } |