source: pmb4.2/trunk/fuentes/pmb/classes/rdf/arc2/parsers/ARC2_AtomParser.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: 7.7 KB
Line 
1<?php
2/*
3homepage: http://arc.semsol.org/
4license:  http://arc.semsol.org/license
5
6class:    ARC2 Atom Parser
7author:   Benjamin Nowack
8version:  2010-11-16
9*/
10
11ARC2::inc('LegacyXMLParser');
12
13class ARC2_AtomParser extends ARC2_LegacyXMLParser {
14
15  function __construct($a, &$caller) {
16    parent::__construct($a, $caller);
17  }
18 
19  function __init() {/* reader */
20    parent::__init();
21    $this->triples = array();
22    $this->target_encoding = '';
23    $this->t_count = 0;
24    $this->added_triples = array();
25    $this->skip_dupes = false;
26    $this->bnode_prefix = $this->v('bnode_prefix', 'arc'.substr(md5(uniqid(rand())), 0, 4).'b', $this->a);
27    $this->bnode_id = 0;
28    $this->cache = array();
29    $this->allowCDataNodes = 0;
30  }
31 
32  /*  */
33 
34  function done() {
35    $this->extractRDF();
36  }
37 
38  /*  */
39 
40  function setReader(&$reader) {
41    $this->reader = $reader;
42  }
43 
44  function createBnodeID(){
45    $this->bnode_id++;
46    return '_:' . $this->bnode_prefix . $this->bnode_id;
47  }
48 
49  function addT($t) {
50    //if (!isset($t['o_datatype']))
51    if ($this->skip_dupes) {
52      //$h = md5(print_r($t, 1));
53      $h = md5(serialize($t));
54      if (!isset($this->added_triples[$h])) {
55        $this->triples[$this->t_count] = $t;
56        $this->t_count++;
57        $this->added_triples[$h] = true;
58      }
59    }
60    else {
61      $this->triples[$this->t_count] = $t;
62      $this->t_count++;
63    }
64  }
65
66  function getTriples() {
67    return $this->v('triples', array());
68  }
69
70  function countTriples() {
71    return $this->t_count;
72  }
73 
74  function getSimpleIndex($flatten_objects = 1, $vals = '') {
75    return ARC2::getSimpleIndex($this->getTriples(), $flatten_objects, $vals);
76  }
77
78  /*  */
79
80  function extractRDF() {
81    $index = $this->getNodeIndex();
82    //print_r($index);
83    $this->rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
84    $this->atom = 'http://www.w3.org/2005/Atom';
85    $this->rss = 'http://purl.org/rss/1.0/';
86    $this->dc = 'http://purl.org/dc/elements/1.1/';
87    $this->sioc = 'http://rdfs.org/sioc/ns#';
88    $this->dct = 'http://purl.org/dc/terms/';
89    $this->content = 'http://purl.org/rss/1.0/modules/content/';
90    $this->enc = 'http://purl.oclc.org/net/rss_2.0/enc#';
91    $this->mappings = array(
92      'feed' => $this->rss . 'channel',
93      'entry' => $this->rss . 'item',
94      'title' => $this->rss . 'title',
95      'link' => $this->rss . 'link',
96      'summary' => $this->rss . 'description',
97      'content' => $this->content . 'encoded',
98      'id' => $this->dc . 'identifier',
99      'author' => $this->dc . 'creator',
100      'category' => $this->dc . 'subject',
101      'updated' => $this->dc . 'date',
102      'source' => $this->dc . 'source',
103    );
104    $this->dt_props = array(
105      $this->dc . 'identifier',
106      $this->rss . 'link'
107    );
108    foreach ($index as $p_id => $nodes) {
109      foreach ($nodes as $pos => $node) {
110        $tag = $this->v('tag', '', $node);
111        if ($tag == 'feed') {
112          $struct = $this->extractChannel($index[$node['id']]);
113          $triples = ARC2::getTriplesFromIndex($struct);
114          foreach ($triples as $t) {
115            $this->addT($t);
116          }
117        }
118        elseif ($tag == 'entry') {
119          $struct = $this->extractItem($index[$node['id']]);
120          $triples = ARC2::getTriplesFromIndex($struct);
121          foreach ($triples as $t) {
122            $this->addT($t);
123          }
124        }
125      }
126    }
127  }
128 
129  function extractChannel($els) {
130    list($props, $sub_index) = $this->extractProps($els, 'channel');
131    $uri = $props[$this->rss . 'link'][0]['value'];
132    return ARC2::getMergedIndex(array($uri => $props), $sub_index);
133  }
134 
135  function extractItem($els) {
136    list($props, $sub_index) = $this->extractProps($els, 'item');
137    $uri = $props[$this->rss . 'link'][0]['value'];
138    return ARC2::getMergedIndex(array($uri => $props), $sub_index);
139  }
140 
141  function extractProps($els, $container) {
142    $r = array($this->rdf . 'type' => array(array('value' => $this->rss . $container, 'type' => 'uri')));
143    $sub_index = array();
144    foreach ($els as $info) {
145      /* key */
146      $tag = $info['tag'];
147      if (!preg_match('/^[a-z0-9]+\:/i', $tag)) {
148        $k = isset($this->mappings[$tag]) ? $this->mappings[$tag] : '';
149      }
150      elseif (isset($this->mappings[$tag])) {
151        $k = $this->mappings[$tag];
152      }
153      else {/* qname */
154        $k = $this->expandPName($tag);
155      }
156      //echo $k . "\n";
157      if (($container == 'channel') && ($k == $this->rss . 'item')) continue;
158      /* val */
159      $v = trim($info['cdata']);
160      if (!$v) $v = $this->v('href uri', '', $info['a']);
161      /* prop */
162      if ($k) {
163        /* content handling */
164        if (in_array($k, array($this->rss . 'description', $this->content . 'encoded'))) {
165          $v = $this->getNodeContent($info);
166        }
167        /* source handling */
168        elseif ($k == $this->dc . 'source') {
169          $sub_nodes = $this->node_index[$info['id']];
170          foreach ($sub_nodes as $sub_pos => $sub_info) {
171            if ($sub_info['tag'] == 'id') {
172              $v = trim($sub_info['cdata']);
173            }
174          }
175        }
176        /* link handling */
177        elseif ($k == $this->rss . 'link') {
178          if ($link_type = $this->v('type', '', $info['a'])) {
179            $k2 = $this->dc . 'format';
180            if (!isset($sub_index[$v])) $sub_index[$v] = array();
181            if (!isset($sub_index[$v][$k2])) $sub_index[$v][$k2] = array();
182            $sub_index[$v][$k2][] = array('value' => $link_type, 'type' => 'literal');
183          }
184        }
185        /* author handling */
186        elseif ($k == $this->dc . 'creator') {
187          $sub_nodes = $this->node_index[$info['id']];
188          foreach ($sub_nodes as $sub_pos => $sub_info) {
189            if ($sub_info['tag'] == 'name') {
190              $v = trim($sub_info['cdata']);
191            }
192            if ($sub_info['tag'] == 'uri') {
193              $k2 = $this->sioc . 'has_creator';
194              $v2 = trim($sub_info['cdata']);
195              if (!isset($r[$k2])) $r[$k2] = array();
196              $r[$k2][] = array('value' => $v2, 'type' => 'uri');
197            }
198          }
199        }
200        /* date handling */
201        elseif (in_array($k, array($this->dc . 'date', $this->dct . 'modified'))) {
202          if (!preg_match('/^[0-9]{4}/', $v) && ($sub_v = strtotime($v)) && ($sub_v != -1)) {
203            $tz = date('Z', $sub_v); /* timezone offset */
204            $sub_v -= $tz; /* utc */
205            $v = date('Y-m-d\TH:i:s\Z', $sub_v);
206          }
207        }
208        /* tag handling */
209        elseif ($k == $this->dc . 'subject') {
210          $v = $this->v('term', '', $info['a']);
211        }
212        /* other attributes in closed tags */
213        elseif (!$v && ($info['state'] == 'closed') && $info['a']) {
214          foreach ($info['a'] as $sub_k => $sub_v) {
215            if (!preg_match('/(xmlns|\:|type)/', $sub_k)) {
216              $v = $sub_v;
217              break;
218            }
219          }
220        }
221        if (!isset($r[$k])) $r[$k] = array();
222        $r[$k][] = array('value' => $v, 'type' => in_array($k, $this->dt_props) || !preg_match('/^[a-z0-9]+\:[^\s]+$/is', $v) ? 'literal' : 'uri');
223      }
224    }
225    return array($r, $sub_index);
226  }
227 
228  function initXMLParser() {
229    if (!isset($this->xml_parser)) {
230      $enc = preg_match('/^(utf\-8|iso\-8859\-1|us\-ascii)$/i', $this->getEncoding(), $m) ? $m[1] : 'UTF-8';
231      $parser = xml_parser_create($enc);
232      xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 0);
233      xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
234      xml_set_element_handler($parser, 'open', 'close');
235      xml_set_character_data_handler($parser, 'cData');
236      xml_set_start_namespace_decl_handler($parser, 'nsDecl');
237      xml_set_object($parser, $this);
238      $this->xml_parser = $parser;
239    }
240  }
241
242  /*  */
243
244
245}
Note: See TracBrowser for help on using the repository browser.