source: Dev/trunk/rdfapi/syntax/RdfParser.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: 66.7 KB
RevLine 
[12]1<?php
2
3// ----------------------------------------------------------------------------------
4// Class: RdfParser
5// ----------------------------------------------------------------------------------
6
7
8/**
9 * An RDF paser.
10 * This class reads RDF data from files or URIs and generates models out of it. All valid
11 * RDF XML syntaxes defined by the W3C in RDF/XML Syntax Specification (Revised)
12 * - W3C Working Draft 10 October 2003
13 * (http://www.w3.org/TR/2003/WD-rdf-syntax-grammar-20031010/) are supported.
14 * The parser is based on the PHP version of repat
15 * (http://phpxmlclasses.sourceforge.net/show_doc.php?class=class_rdf_parser.html)
16 * by Luis Argerich (lrargerich@yahoo.com).
17 *
18 * @version  $Id: RdfParser.php 493 2007-08-12 17:43:07Z cweiske $
19 * @author Luis Argerich <lrargerich@yahoo.com>,
20 *         Chris Bizer <chris@bizer.de>,
21 *         Radoslaw Oldakowski <radol@gmx.de>
22 *                 Daniel Westphal <mail@d-westphal.de>
23 * @package syntax
24 * @access      public
25 *
26 */
27
28class RdfParser extends Object {
29
30var $rdf_parser;
31var $model;
32
33/* Private Methods */
34
35
36/**
37* converts a string to its unicode NFC form (e.g. \uHHHH or \UHHHHHHHH).
38*
39* @param String $str
40* @return String
41* @access private
42*
43*/
44function str2unicode_nfc($str=""){
45        $result="";
46        /* try to detect encoding */
47        $tmp=str_replace("?", "", $str);
48        if(strpos(utf8_decode($tmp), "?")===false){
49                $str=utf8_decode($str);
50        }
51        for($i=0,$i_max=strlen($str);$i<$i_max;$i++){
52                $nr=0;/* unicode dec nr */
53                /* char */
54                $char=$str[$i];
55                /* utf8 binary */
56                $utf8_char=utf8_encode($char);
57                $bytes=strlen($utf8_char);
58                if($bytes==1){
59                        /* 0####### (0-127) */
60                        $nr=ord($utf8_char);
61                }
62                elseif($bytes==2){
63                        /* 110##### 10###### = 192+x 128+x */
64                        $nr=((ord($utf8_char[0])-192)*64) + (ord($utf8_char[1])-128);
65                }
66                elseif($bytes==3){
67                        /* 1110#### 10###### 10###### = 224+x 128+x 128+x */
68                        $nr=((ord($utf8_char[0])-224)*4096) + ((ord($utf8_char[1])-128)*64) + (ord($utf8_char[2])-128);
69                }
70                elseif($bytes==4){
71                        /* 1111#### 10###### 10###### 10###### = 240+x 128+x 128+x 128+x */
72                        $nr=((ord($utf8_char[0])-240)*262144) + ((ord($utf8_char[1])-128)*4096) + ((ord($utf8_char[2])-128)*64) + (ord($utf8_char[3])-128);
73                }
74                /* result (see http://www.w3.org/TR/rdf-testcases/#ntrip_strings) */
75                if($nr<9){/* #x0-#x8 (0-8) */
76                        $result.="\\u".sprintf("%04X",$nr);
77                }
78                elseif($nr==9){/* #x9 (9) */
79                        $result.='\t';
80                }
81                elseif($nr==10){/* #xA (10) */
82                        $result.='\n';
83                }
84                elseif($nr<13){/* #xB-#xC (11-12) */
85                        $result.="\\u".sprintf("%04X",$nr);
86                }
87                elseif($nr==13){/* #xD (13) */
88                        $result.='\t';
89                }
90                elseif($nr<32){/* #xE-#x1F (14-31) */
91                        $result.="\\u".sprintf("%04X",$nr);
92                }
93                elseif($nr<34){/* #x20-#x21 (32-33) */
94                        $result.=$char;
95                }
96                elseif($nr==34){/* #x22 (34) */
97                        $result.='\"';
98                }
99                elseif($nr<92){/* #x23-#x5B (35-91) */
100                        $result.=$char;
101                }
102                elseif($nr==92){/* #x5C (92) */
103                        $result.='\\';
104                }
105                elseif($nr<127){/* #x5D-#x7E (93-126) */
106                        $result.=$char;
107                }
108                elseif($nr<65536){/* #x7F-#xFFFF (128-65535) */
109                        $result.="\\u".sprintf("%04X",$nr);
110                }
111                elseif($nr<1114112){/* #x10000-#x10FFFF (65536-1114111) */
112                        $result.="\\U".sprintf("%08X",$nr);
113                }
114                else{
115                        /* other chars are not defined => ignore */
116                }
117        }
118        return $result;
119}
120
121
122
123
124/**
125 * @access      private
126 */
127function _new_element()
128{
129    $e['parent']=Array();  // Parent is a blank Array
130    $e['state']=0;
131    $e['has_property_atributes']=0;
132    $e['has_member_attributes']=0;
133    $e['subject_type']=0;
134    $e['subject']='';
135    $e['predicate']='';
136    $e['ordinal']=0;
137    $e['members']=0;
138    $e['data']='';
139    $e['xml_lang']='';
140    $e['bag_id']='';
141    $e['statements']=0;
142    $e['statement_id']='';
143    $e['datatype']='';
144    $e['element_base_uri'] = '';
145
146    return $e;
147}
148
149/**
150
151 * @param string $source
152 * @param string &$destination
153 *
154 * @access      private
155 */
156function _copy_element($source, &$destination )
157{
158    if( $source )
159    {
160        $destination['parent'] = $source;
161        $destination['state'] = $source['state'];
162        $destination['xml_lang'] = $source['xml_lang'];
163        $destination['element_base_uri'] = $source['element_base_uri'];
164    }
165}
166
167  /**
168   * @param string &$e
169   * @access    private
170   */
171function _clear_element(&$e)
172{
173        $e['subject']='';
174        $e['predicate']='';
175        $e['data']='';
176        $e['bag_id']='';
177        $e['statement_id']='';
178
179        if(isset($e['parent'])) {
180          if( $e['parent'] )
181          {
182              if( $e['parent']['xml_lang'] != $e['xml_lang'] )
183              {
184                  $e['xml_lang']='';
185              }
186          }
187          else
188          {
189              $e['xml_lang']='';
190          }
191        } else {
192            $e['xml_lang']='';
193        }
194
195        $e['parent']=Array();
196        $e['state']=0;
197        $e['has_property_attributes']=0;
198        $e['has_member_attributes']=0;
199        $e['subject_type']=0;
200        $e['subject']='';
201        $e['predicate']='';
202        $e['ordinal']=0;
203        $e['members']=0;
204        $e['data']='';
205        $e['xml_lang']='';
206        $e['bag_id']='';
207        $e['statements']=0;
208        $e['statement_id']='';
209                $e['datatype']='';
210        $e['element_base_uri'] = '';
211}
212
213  /**
214   * @access    private
215   */
216function _push_element()
217{
218    if(!isset($this->rdf_parser['free'])) {
219        $this->rdf_parser['free']=Array();
220    }
221    if(count($this->rdf_parser['free'])>0)
222    {
223        $e = $this->rdf_parser['free'];
224        if(isset($e['parent'])) {
225          $this->rdf_parser['free'] = $e['parent'];
226        } else {
227          $this->rdf_parser['free']=$this->_new_element();
228        }
229    }
230    else
231    {
232        $e = $this->_new_element();
233    }
234    if(!isset($this->rdf_parser['top'])) {
235      $this->rdf_parser['top']=Array();
236    }
237    $this->_copy_element( $this->rdf_parser['top'], $e );
238    $this->rdf_parser['top'] = $e;
239}
240
241  /**
242   * @access    private
243   */
244function _pop_element()
245{
246    $e = $this->rdf_parser['top'];
247    $this->rdf_parser['top'] = $e['parent'];
248    $this->_clear_element( $e );
249    $this->rdf_parser['free'] = $e;
250}
251
252  /**
253   * @param string $local_name
254   * @access    private
255   */
256function _is_rdf_property_attribute_resource($local_name )
257{
258    return ( $local_name == RDF_TYPE );
259}
260
261  /**
262   * @param string $local_name
263   * @access    private
264   */
265function _is_rdf_property_attribute_literal($local_name )
266{
267    return ( $local_name == RDF_VALUE )
268                || ( $local_name == RDF_BAG )
269                || ( $local_name == RDF_SEQ )
270                || ( $local_name == RDF_ALT )
271                || ( $local_name == RDF_STATEMENT )
272                || ( $local_name == RDF_PROPERTY )
273                || ( $local_name == RDF_LIST );
274}
275
276  /**
277   * @param string $local_name
278   * @access    private
279   */
280function _is_rdf_ordinal( $local_name )
281{
282    $ordinal = -1;
283
284    if( $local_name{0} ==  '_'  )
285    {
286        $ordinal =  substr($local_name,1) + 1 ;
287    }
288
289    return ( $ordinal > 0 ) ? $ordinal : 0;
290}
291
292  /**
293   * @param string $local_name
294   * @access    private
295   */
296function _is_rdf_property_attribute( $local_name )
297{
298    return $this->_is_rdf_property_attribute_resource( $local_name )
299        || $this->_is_rdf_property_attribute_literal( $local_name );
300}
301
302function _is_forbidden_rdf_property_attribute($local_name)
303{
304        return ( $local_name == RDF_RDF )
305                || ( $local_name == RDF_DESCRIPTION)
306        || ( $local_name == RDF_ID)
307        || ( $local_name == RDF_ABOUT )
308        || ( $local_name == RDF_BAG_ID )
309        || ( $local_name == RDF_PARSE_TYPE )
310        || ( $local_name == RDF_RESOURCE )
311        || ( $local_name == RDF_NODEID )
312        || ( $local_name == RDF_LI )
313        || ( $local_name == RDF_ABOUT_EACH )
314                || ( $local_name == RDF_ABOUT_EACH_PREFIX )
315                || ( $local_name == RDF_DATATYPE );
316}
317
318  /**
319   * @param string $local_name
320   * @access    private
321   */
322function _is_rdf_property_element( $local_name )
323{
324    return (  $local_name == RDF_TYPE )
325        || (  $local_name == RDF_SUBJECT )
326        || (  $local_name == RDF_PREDICATE )
327        || (  $local_name == RDF_OBJECT )
328        || (  $local_name == RDF_VALUE )
329        || (  $local_name == RDF_LI )
330        || (  $local_name == RDF_SEEALSO )
331                || ( $local_name == RDF_BAG )
332                || ( $local_name == RDF_SEQ )
333                || ( $local_name == RDF_ALT )
334                || ( $local_name == RDF_STATEMENT )
335                || ( $local_name == RDF_PROPERTY )
336                || ( $local_name == RDF_LIST )
337                || ( $local_name == RDF_FIRST )
338                || ( $local_name == RDF_REST )
339        || (  $local_name{0} == '_'  );
340}
341
342  /**
343   * @param string $local_name
344   * @access    private
345   */
346function _is_forbidden_rdf_property_element ($local_name)
347{
348        return ( $local_name == RDF_RDF )
349                || ( $local_name == RDF_DESCRIPTION)
350        || ( $local_name == RDF_ID)
351        || ( $local_name == RDF_ABOUT )
352        || ( $local_name == RDF_BAG_ID )
353        || ( $local_name == RDF_PARSE_TYPE )
354        || ( $local_name == RDF_RESOURCE )
355        || ( $local_name == RDF_NODEID )
356        || ( $local_name == RDF_ABOUT_EACH )
357                || ( $local_name == RDF_ABOUT_EACH_PREFIX )
358                || ( $local_name == RDF_DATATYPE );
359}
360
361
362  /**
363   * @param string $local_name
364   * @access    private
365   */
366function _is_rdf_node_element( $local_name )
367{
368    return ( $local_name == RDF_DESCRIPTION )
369        || ( $local_name == RDF_STATEMENT )
370        || ( $local_name == RDF_SUBJECT )
371        || ( $local_name == RDF_PREDICATE )
372        || ( $local_name == RDF_OBJECT )
373        || ( $local_name == RDF_PROPERTY )
374                || ( $local_name == RDF_TYPE )
375        || ( $local_name == RDF_VALUE )
376                || ( $local_name == RDF_BAG )
377                || ( $local_name == RDF_SEQ )
378                || ( $local_name == RDF_ALT )
379        || ( $local_name == RDF_SEEALSO )
380                || ( $local_name == RDF_LIST )
381                || ( $local_name == RDF_FIRST )
382                || ( $local_name == RDF_REST )
383                || ( $local_name == RDF_NIL )
384        || ( $local_name{0} == '_'  );
385}
386
387  /**
388   * @param string $local_name
389   * @access    private
390   */
391function _is_forbidden_rdf_node_element ($local_name)
392{
393        return ( $local_name == RDF_RDF )
394        || ( $local_name == RDF_ID)
395        || ( $local_name == RDF_ABOUT )
396        || ( $local_name == RDF_BAG_ID )
397        || ( $local_name == RDF_PARSE_TYPE )
398        || ( $local_name == RDF_RESOURCE )
399        || ( $local_name == RDF_NODEID )
400                || ( $local_name == RDF_LI )
401        || ( $local_name == RDF_ABOUT_EACH )
402                || ( $local_name == RDF_ABOUT_EACH_PREFIX )
403                || ( $local_name == RDF_DATATYPE );
404}
405
406  /**
407   * @param string $val
408   * @access    private
409   */
410function _istalnum($val) {
411  return preg_match('/([A-Za-z0-9])/',$val);
412}
413  /**
414   * @param string $val
415   * @access    private
416   */
417function _istalpha($val) {
418  return preg_match('/([A-Za-z])/',$val);
419}
420
421  /**
422   * @param string $uri
423   * @access    private
424   */
425function _is_absolute_uri($uri )
426{
427    $result = false;
428        $uri_p=0;
429    if( $uri && $this->_istalpha( $uri{$uri_p} ) )
430    {
431        ++$uri_p;
432
433        while( ($uri_p<strlen($uri))
434            && ( $this->_istalnum( $uri{$uri_p} )
435                || ( $uri{$uri_p} ==  '+'  )
436                || ( $uri{$uri_p} == '-'  )
437                || ( $uri{$uri_p} ==  '.'  ) ) )
438        {
439                ++$uri_p;
440        }
441
442        $result = ( $uri{$uri_p} == ':'  );
443    }
444    return $result;
445}
446
447
448/*
449   * This function returns an associative array returning any of the various components of the URL that are present. This includes the
450   * $arr=parse_url($url)
451   * scheme - e.g. http
452   * host
453   * port
454   * user
455   * pass
456   * path
457   * query - after the question mark ?
458   * fragment - after the hashmark #
459   *
460   * @param string $uri
461   * @param string $buffer
462   * @param string &$scheme
463   * @param string &$authority
464   * @param string &$path
465   * @param string &$query
466   * @param string &$fragment
467   * @access    private
468*/
469function _parse_uri($uri,$buffer,&$scheme,&$authority,&$path,&$query,&$fragment ) {
470
471  $parsed=parse_url($uri);
472  if(isset($parsed['scheme'])) {
473    $scheme=$parsed['scheme'];
474  } else {
475    $scheme='';
476  }
477  if(isset($parsed['host'])) {
478    $host=$parsed['host'];
479  } else {
480    $host='';
481  }
482  if(isset($parsed['host'])) {
483    $authority=$parsed['host'];
484  } else {
485    $authority='';
486  }
487  if(isset($parsed['path'])) {
488    $path=$parsed['path'];
489  } else {
490    $path='';
491  }
492  if(isset($parsed['query'])) {
493    $query=$parsed['query'];
494  } else {
495    $query='';
496  }
497  if(isset($parsed['fragment'])) {
498    $fragment=$parsed['fragment'];
499  } else {
500    $fragment='';
501  }
502
503}
504
505/**
506   * @param string $base_uri
507   * @param string $reference_uri
508   * @param string &$buffer
509   * @access    private
510*/
511function _resolve_uri_reference($base_uri,$reference_uri,&$buffer )
512{
513        if ($reference_uri == '')
514                return ($buffer = preg_replace("/\#[^\/\\\]*$/", '', $base_uri));
515
516    $base_buffer='';
517    $reference_buffer='';
518    $path_buffer='';
519
520    $buffer = '';
521
522    $this->_parse_uri($reference_uri,
523                                  $reference_buffer,
524                                  $reference_scheme,
525                                  $reference_authority,
526                      $reference_path,
527                      $reference_query,
528                      $reference_fragment );
529
530    $this->_parse_uri($base_uri,
531                          $base_buffer,
532                          $base_scheme,
533                          $base_authority,
534                          $base_path,
535                          $base_query,
536                      $base_fragment );
537
538    if( $reference_scheme == ''
539        && $reference_authority == ''
540        && $reference_path == ''
541        && $reference_query == '' )
542    {
543        $buffer=$base_uri;
544
545        if( $reference_fragment != '' )
546        {
547                        if ($base_path == '' || $base_path == '/' || $base_path == "\\") {
548                           $buffer = $this->rdf_parser['document_base_uri'];
549                        }
550                        else
551                        {
552                                $buffer = preg_replace("/\#[^\/\\\]*$/", '', $base_uri);
553                        }
554
555            // CB: Changed for base URI
556                        $c = substr($buffer, strlen($buffer)-1 ,1);
557                if (!($c=='#' || $c==':' || $c=='/' || $c=="\\"))
558                               $buffer.= '#' ;
559            $buffer.=$reference_fragment;
560
561        }
562    }
563    else if( $reference_scheme != '' )
564    {
565        $buffer=$reference_uri;
566    }
567    else
568    {
569        $result_scheme = $base_scheme;
570        $result_path = '';
571
572        if( $reference_authority != '' )
573        {
574            $result_authority = $reference_authority;
575        }
576        else
577        {
578            $result_authority = $base_authority;
579
580            if ($reference_path != '')
581            {
582                if ($reference_path{0} == '/' || $reference_path{0} == "\\")
583                {
584                        if ($reference_path{1} == '/' || $reference_path{1} == "\\")
585                        {
586                                                $result_authority = '';
587                                                $result_path = $reference_path;
588                        }
589                        else
590                                $result_path = $reference_path;
591                }
592                elseif (substr($reference_path, 0, 3) == '../' ||
593                        substr($reference_path, 0, 3) == '..\\')
594                {
595                        $slash = $reference_path{2};
596                        while($base_path != '' && ( substr($reference_path, 0, 3) == '../'
597                                             || substr($reference_path, 0, 3) == '..\\'))
598                    {
599                                $base_path = preg_replace("/((\/)|(\\\))[^\/\\\]*$/", '', $base_path);
600                                if ($base_path != '') {
601                                   $base_path = preg_replace("/((\/)|(\\\))[^\/\\\]*$/", '', $base_path);
602                                   $reference_path = substr($reference_path, 3);
603                                }
604                        }
605
606                    $result_path = $base_path .$slash .$reference_path;
607                }
608                else
609                {
610                        if ($base_path)
611                                $result_path = preg_replace("/[^\/\\\]*$/", $reference_path, $base_path, 1);
612                                        else
613                                            $result_path = '/' .$reference_path;
614                }
615            }
616
617        }
618
619        if( $result_scheme != '' )
620        {
621            $buffer=$result_scheme;
622            $buffer.=':';
623        }
624
625        if( $result_authority != '' )
626        {
627            $buffer.="//";
628            $buffer.=$result_authority;
629        }
630
631        if( $result_path != '' )
632        {
633            $buffer.=$result_path;
634        }
635
636        if( $reference_query != '' )
637        {
638            $buffer.='?';
639            $buffer.=$reference_query;
640        }
641
642        if( $reference_fragment != '' )
643        {
644            $buffer.='#';
645            $buffer.=$reference_fragment;
646        }
647    }
648}
649
650
651/**
652   * IDs which contain CombiningChars or Extenders
653   * (see http://www.w3.org/TR/REC-xml-names/#NT-NCName) are assumed to be invalid.
654   * If you want to use IDs containing these characters you can turn off
655   * the validating by setting the constant VALIDATE_IDS to FALSE (see constants.php).
656   *
657   * @param string $id
658   * @access    private
659*/
660function is_valid_id($id )
661{
662        if (!VALIDATE_IDS)
663                return TRUE;
664
665    $result = FALSE;
666
667    if( $id )
668    {
669        if( $this->_istalpha($id{0}) || $id{0} == '_')
670        {
671            $result = TRUE;
672            $i=0;
673            $len = strlen($id);
674                        while( $result != FALSE && ++$i < $len )
675            {
676                if( !($this->_istalnum( $id{$i})
677                      || $id{$i} == '.'
678                      || $id{$i} == '-'
679                      || $id{$i} == '_'))
680                {
681                   $result = FALSE;
682                }
683            }
684        }
685    }
686
687    if (!$result)
688        $this->_report_error('illegal ID, nodeID or bagID attribute value');
689    else
690        return TRUE;
691}
692
693/**
694   * @param string $id
695   * @param string &$buffer
696   * @access    private
697*/
698function _resolve_id($id,&$buffer )
699{
700    $id_buffer='';
701
702    if( $this->is_valid_id($id) )
703    {
704        $id_buffer="#$id";
705    }
706
707    $this->_resolve_uri_reference( $this->rdf_get_base(), $id_buffer, $buffer );
708
709}
710
711/**
712   * @param string $name
713   * @param string &$buffer
714   * @param string &$namespace_uri
715   * @param string &$local_name
716   * @access    private
717*/
718function _split_name($name, &$buffer, &$namespace_uri, &$local_name )
719{
720    static $nul = 0;
721    $buffer=$name;
722
723        if(  strstr( $buffer, NAMESPACE_SEPARATOR_CHAR ) )
724        {
725            $cosas=explode(NAMESPACE_SEPARATOR_CHAR,$buffer);
726            $namespace_uri = $cosas[0];
727            $local_name = $cosas[1];
728        }
729        else
730        {
731            if( ( $buffer{ 0 } ==  'x'  )
732                && ( $buffer{ 1 } ==  'm'  )
733                && ( $buffer{ 2 } ==  'l'  )
734                && ( $buffer{ 3 } ==  ':'  ) )
735            {
736                $namespace_uri = XML_NAMESPACE_URI;
737                $local_name = substr($buffer,4);
738            }
739            else
740            {
741                $namespace_uri = '';
742                $local_name = $buffer;
743            }
744        }
745}
746/**
747   * @param string &$buf
748   * @access    private
749*/
750function _generate_anonymous_uri(&$buf )
751{
752    $id='';
753    if(!isset($this->rdf_parser['anonymous_id'])) {
754      $this->rdf_parser['anonymous_id']=0;
755    }
756    $this->rdf_parser['anonymous_id']++;
757
758    $buf= BNODE_PREFIX . $this->rdf_parser['anonymous_id'];
759
760}
761/**
762   * @param string $subject_type
763   * @param string $subject
764   * @param string $predicate
765   * @param string $ordinal
766   * @param string $object_type
767   * @param string $object
768   * @param string $xml_lang
769   * @param string $bag_id
770   * @param string $statements
771   * @param string $statement_id
772   * @access    private
773*/
774function _report_statement( $subject_type, $subject, $predicate, $ordinal, $object_type,  $object, $xml_lang, $bag_id, $statements, $statement_id, $datatype )
775{
776    $statement_id_type = RDF_SUBJECT_TYPE_URI;
777    $statement_id_buffer='';
778    $predicate_buffer='';
779    if (!$xml_lang && $object_type == RDF_OBJECT_TYPE_LITERAL && isset($this->rdf_parser['document_xml_lang']))
780        $xml_lang = $this->rdf_parser['document_xml_lang'];
781
782         // call add statement
783         $this->add_statement_to_model($this->rdf_parser['user_data'],$subject_type,$subject,$predicate,$ordinal,$object_type,$object,$xml_lang, $datatype );
784
785        if( $bag_id )
786        {
787            if( $statements == '' )
788            {
789                $this->_report_statement(RDF_SUBJECT_TYPE_URI,
790                    $bag_id,
791                    RDF_NAMESPACE_URI.RDF_TYPE,
792                    0,
793                    RDF_OBJECT_TYPE_RESOURCE,
794                    RDF_NAMESPACE_URI.RDF_BAG,
795                    '',
796                    '',
797                    '',
798                    '',
799                                        $datatype );
800            }
801
802            if( ! $statement_id )
803            {
804                $statement_id_type = RDF_SUBJECT_TYPE_BNODE;
805                $this->_generate_anonymous_uri( $statement_id_buffer );
806                $statement_id = $statement_id_buffer;
807            }
808            $statements++;
809            $predicate_buffer='RDF_NAMESPACE_URI_'.$statements;
810
811            $this->_report_statement(
812                RDF_SUBJECT_TYPE_URI,
813                $bag_id,
814                $predicate_buffer,
815                $statements,
816                RDF_OBJECT_TYPE_BNODE,
817                $statement_id,
818                '',
819                '',
820                '',
821                '',
822                                $datatype );
823        }
824
825        if( $statement_id )
826        {
827            // rdf:type = rdf:Statement
828            $this->_report_statement(
829                $statement_id_type,
830                $statement_id,
831                RDF_NAMESPACE_URI.RDF_TYPE,
832                0,
833                RDF_OBJECT_TYPE_RESOURCE,
834                RDF_NAMESPACE_URI.RDF_STATEMENT,
835                '',
836                '',
837                '',
838                '',
839                                $datatype );
840
841                        if ($subject_type == RDF_SUBJECT_TYPE_BNODE)
842                           $obj_type = RDF_OBJECT_TYPE_BNODE;
843                        else
844                           $obj_type = RDF_OBJECT_TYPE_RESOURCE;
845
846
847            // rdf:subject
848            $this->_report_statement(
849                $statement_id_type,
850                $statement_id,
851                RDF_NAMESPACE_URI.RDF_SUBJECT,
852                0,
853                                $obj_type,
854                $subject,
855                '',
856                '',
857                '',
858                '',
859                                $datatype );
860
861            // rdf:predicate
862            $this->_report_statement(
863                $statement_id_type,
864                $statement_id,
865                RDF_NAMESPACE_URI.RDF_PREDICATE,
866                0,
867                RDF_OBJECT_TYPE_RESOURCE,
868                $predicate,
869                '',
870                '',
871                '',
872                '',
873                                $datatype );
874
875            // rdf:object
876            $this->_report_statement(
877                $statement_id_type,
878                $statement_id,
879                RDF_NAMESPACE_URI.RDF_OBJECT,
880                0,
881                $object_type,
882                $object,
883                '',
884                '',
885                '',
886                '',
887                                $datatype );
888        }
889}
890/**
891   * @param string $subject_type
892   * @param string $subject
893   * @param string $attributes
894   * @param string $xml_lang
895   * @param string $bag_id
896   * @param string $statements
897 * @access      private
898*/
899function _handle_property_attributes($subject_type, $subject, $attributes, $xml_lang, $bag_id, $statements )
900{
901    $i=0;
902
903    $attribute='';
904    $predicate='';
905
906    $attribute_namespace_uri='';
907    $attribute_local_name='';
908    $attribute_value='';
909
910    $ordinal=0;
911
912    for( $i = 0; isset($attributes[ $i ]); $i += 2 )
913    {
914        $this->_split_name(
915            $attributes[ $i ],
916            $attribute,
917            $attribute_namespace_uri,
918            $attribute_local_name );
919
920        $attribute_value = $attributes[ $i + 1 ];
921
922        $predicate=$attribute_namespace_uri;
923        $predicate.=$attribute_local_name;
924
925        if( RDF_NAMESPACE_URI == $attribute_namespace_uri )
926        {
927            if( $this->_is_rdf_property_attribute_literal( $attribute_local_name ) )
928            {
929                                $this->_report_statement(
930                    $subject_type,
931                    $subject,
932                    $predicate,
933                    0,
934                    RDF_OBJECT_TYPE_LITERAL,
935                    $attribute_value,
936                    $xml_lang,
937                    $bag_id,
938                    $statements,
939                    '',
940                                        '');
941            }
942            else if( $this->_is_rdf_property_attribute_resource( $attribute_local_name ) )
943            {
944                                $this->_report_statement(
945                    $subject_type,
946                    $subject,
947                    $predicate,
948                    0,
949                    RDF_OBJECT_TYPE_RESOURCE,
950                    $attribute_value,
951                    '',
952                    $bag_id,
953                    $statements,
954                    '',
955                                        '');
956            }
957            else if( ( $ordinal = $this->_is_rdf_ordinal( $attribute_local_name ) ) != 0 )
958            {
959                                $this->_report_statement(
960                    $subject_type,
961                    $subject,
962                    $predicate,
963                    $ordinal,
964                    RDF_OBJECT_TYPE_LITERAL,
965                    $attribute_value,
966                    $xml_lang,
967                    $bag_id,
968                    $statements,
969                    '',
970                                        '' );
971            }
972            else if (   ($attribute_local_name != RDF_ABOUT)
973                     && ($attribute_local_name != RDF_RDF)
974                     && ($attribute_local_name != RDF_DESCRIPTION)
975                     && ($attribute_local_name != RDF_ID)
976                     && ($attribute_local_name != RDF_ABOUT_EACH)
977                     && ($attribute_local_name != RDF_ABOUT_EACH_PREFIX)
978                     && ($attribute_local_name != RDF_BAG_ID)
979                     && ($attribute_local_name != RDF_RESOURCE)
980                     && ($attribute_local_name != RDF_PARSE_TYPE)
981                     && ($attribute_local_name != RDF_PARSE_TYPE_LITERAL)
982                     && ($attribute_local_name != RDF_PARSE_TYPE_RESOURCE)
983                     && ($attribute_local_name != RDF_LI)
984                     && ($attribute_local_name != RDF_SUBJECT)
985                     && ($attribute_local_name != RDF_PREDICATE)
986                     && ($attribute_local_name != RDF_OBJECT)
987                     && ($attribute_local_name != RDF_NODEID)
988                     && ($attribute_local_name != RDF_DATATYPE)
989                     && ($attribute_local_name != RDF_SEEALSO)
990                     && ($attribute_local_name != RDF_NIL)
991                     && ($attribute_local_name != RDF_REST)
992                     && ($attribute_local_name != RDF_FIRST)
993                    )
994            {
995                $this->_report_statement(
996                        $subject_type,
997                        $subject,
998                        $predicate,
999                        0,
1000                        RDF_OBJECT_TYPE_LITERAL,
1001                        $attribute_value,
1002                        $xml_lang,
1003                        $bag_id,
1004                        $statements,
1005                        '',
1006                                        '' );
1007            }
1008        }
1009        else if( XML_NAMESPACE_URI == $attribute_namespace_uri )
1010        {
1011                        if ($attribute_local_name == 'base')
1012                        {
1013                        $this->rdf_parser['top']['element_base_uri'] = $attribute_value;
1014                        }
1015        }
1016        else if( $attribute_namespace_uri )
1017        {
1018            // is it required that property attributes be in an explicit namespace?
1019
1020                        $this->_report_statement(
1021                $subject_type,
1022                $subject,
1023                $predicate,
1024                0,
1025                RDF_OBJECT_TYPE_LITERAL,
1026                $attribute_value,
1027                $xml_lang,
1028                $bag_id,
1029                $statements,
1030                '',
1031                                '' );
1032        }
1033    }
1034}
1035
1036
1037
1038/**
1039   * @param string $warning
1040 * @access      private
1041*/
1042function _report_warning($warning)
1043{
1044        $errmsg = RDFAPI_ERROR . '(class: parser): ' . $warning .'.';
1045        trigger_error($errmsg, E_USER_WARNING);
1046}
1047
1048
1049function _report_error($error)
1050{
1051        $errmsg = RDFAPI_ERROR . '(class: parser): ' . $error .'.';
1052        trigger_error($errmsg, E_USER_ERROR);
1053}
1054
1055
1056/**
1057   * @param string $namespace_uri
1058   * @param string $local_name
1059   * @param string $attributes
1060   * @param string $parent
1061 * @access      private
1062*/
1063function _handle_resource_element( $namespace_uri, $local_name, $attributes, $parent )
1064{
1065    $subjects_found = 0;
1066    $aux=$attributes;
1067    $aux2=Array();
1068    foreach($attributes as $atkey=>$atvalue) {
1069      $aux2[]=$atkey;
1070      $aux2[]=$atvalue;
1071    }
1072    $attributes=$aux2;
1073    $id = '';
1074    $about = '';
1075
1076    $bag_id = '';
1077    $node_id = '';
1078    $datatype = '';
1079
1080    $i=0;
1081
1082    $attribute='';
1083
1084    $attribute_namespace_uri='';
1085    $attribute_local_name='';
1086    $attribute_value='';
1087
1088    $id_buffer='';
1089
1090    $type='';
1091
1092    $this->rdf_parser['top']['has_property_attributes'] = false;
1093    $this->rdf_parser['top']['has_member_attributes'] = false;
1094
1095
1096    if( $namespace_uri == RDF_NAMESPACE_URI )
1097    {
1098       if( ! $this->_is_rdf_node_element( $local_name ) )
1099       {
1100                  $msg = 'unknown or out of context rdf node element: '.$local_name;
1101
1102                  if ($this->_is_forbidden_rdf_node_element($local_name))
1103                         $this->_report_error($msg);
1104                  else
1105                         $this->_report_warning($msg);
1106       }
1107    }
1108
1109    // examine each attribute for the standard RDF "keywords"
1110    for( $i = 0; isset($attributes[$i]); $i += 2 )
1111    {
1112        $this->_split_name(
1113            $attributes[ $i ],
1114            $attribute,
1115            $attribute_namespace_uri,
1116            $attribute_local_name );
1117
1118        $attribute_value = $attributes[ $i + 1 ];
1119
1120        // if the attribute is not in any namespace
1121        //   or the attribute is in the RDF namespace
1122        if( ( $attribute_namespace_uri == '' )
1123            || (  $attribute_namespace_uri == RDF_NAMESPACE_URI  ))
1124        {
1125            if( $attribute_local_name == RDF_ID )
1126            {
1127                $id = $attribute_value;
1128                ++$subjects_found;
1129            } else if( $attribute_local_name == RDF_ABOUT ) {
1130                                $about = '_'.$attribute_value;
1131                ++$subjects_found;
1132            } else if( $attribute_local_name == RDF_NODEID) {
1133                $node_id = $attribute_value;
1134                                ++$subjects_found;
1135            } else if(  $attribute_local_name == RDF_ABOUT_EACH ) {
1136                                $error = 'aboutEach has been removed from the RDF specifications';
1137                                $this->_report_error($error);
1138            } else if( $attribute_local_name == RDF_ABOUT_EACH_PREFIX ) {
1139                                $error = 'aboutEachPrefix has been removed from the RDF specifications';
1140                                $this->_report_error($error);
1141            } else if( $attribute_local_name == RDF_BAG_ID) {
1142                $bag_id = $attribute_value;
1143            } else if( $attribute_local_name == RDF_DATATYPE) {
1144                $datatype = $attribute_value;
1145            } else if( $this->_is_rdf_property_attribute( $attribute_local_name )) {
1146                $this->rdf_parser['top']['has_property_attributes'] = true;
1147            } else if( $this->_is_rdf_ordinal( $attribute_local_name )) {
1148                $this->rdf_parser['top']['has_property_attributes'] = true;
1149                $this->rdf_parser['top']['has_member_attributes'] = true;
1150            } else {
1151                                $this->rdf_parser['top']['has_property_attributes'] = true;
1152                                $msg = 'unknown or out of context rdf attribute: '.$attribute_local_name;
1153
1154                                if ($this->_is_forbidden_rdf_property_attribute($attribute_local_name))
1155                                        $this->_report_error($msg);
1156                                else
1157                                        $this->_report_warning($msg);
1158            }
1159        }
1160        else if(  $attribute_namespace_uri == XML_NAMESPACE_URI )
1161        {
1162            if( $attribute_local_name == XML_LANG )
1163            {
1164                $this->rdf_parser['top']['xml_lang'] = $attribute_value;
1165            }
1166                elseif ($attribute_local_name == 'base')
1167                {
1168                        $this->rdf_parser['top']['element_base_uri'] = $attribute_value;
1169                }
1170        }
1171        else if( $attribute_namespace_uri )
1172        {
1173            $this->rdf_parser['top']['has_property_attributes'] = true;
1174        }
1175    }
1176
1177    // if no subjects were found, generate one.
1178    if( $subjects_found == 0 )
1179    {
1180        $this->_generate_anonymous_uri( $id_buffer );
1181        $this->rdf_parser['top']['subject']=$id_buffer;
1182                $this->rdf_parser['top']['subject_type'] = RDF_SUBJECT_TYPE_BNODE;
1183    }
1184    else if( $subjects_found > 1 )
1185    {
1186                 $this->_report_error('ID, about and nodeID are mutually exclusive');
1187    }
1188    else if( $id )
1189    {
1190        $this->_resolve_id( $id, $id_buffer );
1191        $this->rdf_parser['top']['subject_type'] = RDF_SUBJECT_TYPE_URI;
1192        $this->rdf_parser['top']['subject']=$id_buffer;
1193    }
1194    else if( $about )
1195    {
1196                $this->_resolve_uri_reference( $this->rdf_get_base(), substr($about,1), $id_buffer );
1197        $this->rdf_parser['top']['subject_type'] = RDF_SUBJECT_TYPE_URI;
1198        $this->rdf_parser['top']['subject']=$id_buffer;
1199    }
1200    else if( $node_id )
1201    {
1202        $this->is_valid_id($node_id);
1203        $this->rdf_parser['top']['subject_type'] = RDF_SUBJECT_TYPE_BNODE;
1204        $this->rdf_parser['top']['subject']=$node_id;
1205    }
1206
1207    // if the subject is empty, assign it the document uri
1208    if( $this->rdf_parser['top']['subject'] == '' )
1209    {
1210                $this->rdf_parser['top']['subject']=$this->rdf_get_base();
1211    }
1212
1213    if( $bag_id )
1214    {
1215        $this->_resolve_id( $bag_id, $id_buffer );
1216        $this->rdf_parser['top']['bag_id']=$id_buffer;
1217    }
1218
1219    // only report the type for non-rdf:Description elements.
1220    if( ($local_name != RDF_DESCRIPTION )
1221        || ( $namespace_uri != RDF_NAMESPACE_URI ) )
1222    {
1223        $type=$namespace_uri;
1224        $type.=$local_name;
1225
1226                $this->_report_statement(
1227            $this->rdf_parser['top']['subject_type'],
1228            $this->rdf_parser['top']['subject'],
1229            RDF_NAMESPACE_URI.RDF_TYPE,
1230            0,
1231            RDF_OBJECT_TYPE_RESOURCE,
1232            $type,
1233            '',
1234            $this->rdf_parser['top']['bag_id'],
1235            $this->rdf_parser['top']['statements'],
1236            '',
1237                        $datatype);
1238
1239    }
1240
1241    // if this element is the child of some property,
1242    //   report the appropriate statement.
1243    if( $parent )
1244    {
1245        if ($this->rdf_parser['top']['subject_type'] == RDF_SUBJECT_TYPE_BNODE)
1246                $objtype = RDF_OBJECT_TYPE_BNODE;
1247        else
1248                $objtype = RDF_OBJECT_TYPE_RESOURCE;
1249
1250        $this->_report_statement(
1251            $parent['parent']['subject_type'],
1252            $parent['parent']['subject'],
1253            $parent['predicate'],
1254            $parent['ordinal'],
1255            $objtype,
1256            $this->rdf_parser['top']['subject'],
1257            '',
1258            $parent['parent']['bag_id'],
1259            $parent['parent']['statements'],
1260            $parent['statement_id'],
1261                        $parent['datatype']);
1262
1263    }
1264
1265    if( $this->rdf_parser['top']['has_property_attributes'] )
1266    {
1267        $this->_handle_property_attributes(
1268            $this->rdf_parser['top']['subject_type'],
1269            $this->rdf_parser['top']['subject'],
1270            $attributes,
1271            $this->rdf_parser['top']['xml_lang'],
1272            $this->rdf_parser['top']['bag_id'],
1273            $this->rdf_parser['top']['statements'] );
1274    }
1275}
1276
1277/**
1278   * @param string &$namespace_uri
1279   * @param string &$local_name
1280   * @param string &$attributes
1281 * @access      private
1282*/
1283function _handle_property_element( &$namespace_uri, &$local_name, &$attributes )
1284{
1285    $buffer='';
1286
1287    $i=0;
1288
1289    $aux=$attributes;
1290    $aux2=Array();
1291    foreach($attributes as $atkey=>$atvalue) {
1292      $aux2[]=$atkey;
1293      $aux2[]=$atvalue;
1294    }
1295    $attributes=$aux2;
1296
1297    $attribute_namespace_uri='';
1298    $attribute_local_name='';
1299    $attribute_value = '';
1300
1301    $resource = NULL;
1302    $statement_id = '';
1303    $bag_id = '';
1304    $parse_type = '';
1305        $node_id = '';
1306        $datatype = '';
1307
1308    $this->rdf_parser['top']['ordinal'] = 0;
1309
1310    if( $namespace_uri == RDF_NAMESPACE_URI )
1311    {
1312       if( ! $this->_is_rdf_property_element( $local_name ) )
1313        {
1314                        $msg = 'unknown or out of context rdf property element: '.$local_name;
1315
1316                        if ($this->_is_forbidden_rdf_property_element($local_name))
1317                                $this->_report_error($msg);
1318                        else
1319                                $this->_report_warning($msg);
1320        }
1321
1322    }
1323
1324    $buffer=$namespace_uri;
1325
1326    if( ( $namespace_uri == RDF_NAMESPACE_URI )
1327        &&  ( $local_name == RDF_LI ) )
1328    {
1329        $this->rdf_parser['top']['parent']['members']++;
1330        $this->rdf_parser['top']['ordinal'] = $this->rdf_parser['top']['parent']['members'];
1331
1332        $this->rdf_parser['top']['ordinal']=$this->rdf_parser['top']['ordinal'];
1333
1334        $buffer.='_'.$this->rdf_parser['top']['ordinal'];
1335
1336    }
1337    else
1338    {
1339        $buffer.=$local_name;
1340    }
1341
1342    $this->rdf_parser['top']['predicate']=$buffer;
1343
1344    $this->rdf_parser['top']['has_property_attributes'] = false;
1345    $this->rdf_parser['top']['has_member_attributes'] = false;
1346
1347
1348    for( $i = 0; isset($attributes[$i]); $i += 2 )
1349    {
1350        $this->_split_name(
1351            $attributes[$i],
1352            $buffer,
1353            $attribute_namespace_uri,
1354            $attribute_local_name );
1355
1356        $attribute_value = $attributes[$i + 1];
1357
1358        // if the attribute is not in any namespace
1359        //   or the attribute is in the RDF namespace
1360        if( ( $attribute_namespace_uri == '' )
1361            || (  $attribute_namespace_uri == RDF_NAMESPACE_URI ) )
1362        {
1363            if( ( $attribute_local_name == RDF_ID )  )
1364            {
1365                $statement_id = $attribute_value;
1366            }
1367            else if( $attribute_local_name == RDF_PARSE_TYPE )
1368            {
1369                $parse_type = $attribute_value;
1370            }
1371            else if(  $attribute_local_name == RDF_RESOURCE )
1372            {
1373                $resource = $attribute_value;
1374            }
1375                        else if(  $attribute_local_name == RDF_NODEID )
1376            {
1377                                $node_id = $attribute_value;
1378            }
1379            else if(  $attribute_local_name == RDF_BAG_ID )
1380            {
1381                $bag_id = $attribute_value;
1382            }
1383                        else if(  $attribute_local_name == RDF_DATATYPE )
1384            {
1385                                $datatype = $attribute_value;
1386                                $this->rdf_parser['top']['datatype'] = $attribute_value;
1387            }
1388            else if( $this->_is_rdf_property_attribute( $attribute_local_name ) )
1389            {
1390                $this->rdf_parser['top']['has_property_attributes'] = true;
1391            }
1392            else
1393            {
1394                $this->_report_warning('unknown rdf attribute: '.$attribute_local_name );
1395                return;
1396            }
1397        }
1398        else if(  $attribute_namespace_uri == XML_NAMESPACE_URI  )
1399        {
1400            if( $attribute_local_name == XML_LANG  )
1401            {
1402                $this->rdf_parser['top']['xml_lang'] = $attribute_value;
1403            }
1404                elseif ($attribute_local_name == 'base')
1405                {
1406                        $this->rdf_parser['top']['element_base_uri'] = $attribute_value;
1407                }
1408        }
1409        else if( $attribute_namespace_uri )
1410        {
1411            $this->rdf_parser['top']['has_property_attributes'] = true;
1412        }
1413    }
1414
1415    if( $statement_id )
1416    {
1417            $this->_resolve_id($statement_id, $buffer );
1418        $this->rdf_parser['top']['statement_id']=$buffer;
1419    }
1420
1421        if ($node_id)
1422        {
1423                $this->is_valid_id($node_id);
1424
1425                if ($resource)
1426                {
1427                        $this->_report_error('nodeID and resource are mutually exclusive');
1428                }
1429        if ($statement_id)
1430        {
1431                // reify statement
1432                $this->_report_statement(
1433                        $this->rdf_parser['top']['parent']['subject_type'],
1434                        $this->rdf_parser['top']['parent']['subject'],
1435                        $this->rdf_parser['top']['predicate'],
1436                        $this->rdf_parser['top']['ordinal'],
1437                        RDF_OBJECT_TYPE_BNODE,
1438                        $node_id,
1439                        '',
1440                        $this->rdf_parser['top']['parent']['bag_id'],
1441                        $this->rdf_parser['top']['parent']['statements'],
1442                        $this->rdf_parser['top']['statement_id'],
1443                                '');
1444                        $statement_id = '';
1445        }
1446        else
1447        {
1448                        $this->_report_statement(
1449                   $this->rdf_parser['top']['parent']['subject_type'],
1450                   $this->rdf_parser['top']['parent']['subject'],
1451                   $this->rdf_parser['top']['predicate'],
1452                   $this->rdf_parser['top']['ordinal'],
1453                   RDF_OBJECT_TYPE_BNODE,
1454                   $node_id,
1455                   '',
1456                   $this->rdf_parser['top']['parent']['bag_id'],
1457                   $this->rdf_parser['top']['parent']['statements'],
1458                   '',
1459                           $datatype );
1460        }
1461
1462        $this->rdf_parser['top']['state'] = IN_PROPERTY_EMPTY_RESOURCE;
1463        }
1464
1465    if( $parse_type )
1466        {
1467        if( $resource ) {
1468                        $this->_report_error('property elements with rdf:parseType do not allow rdf:resource' );
1469        }
1470
1471        if( $bag_id ) {
1472            $this->_report_warning('property elements with rdf:parseType do not allow rdf:bagID' );
1473            return;
1474        }
1475
1476        if( $this->rdf_parser['top']['has_property_attributes'] )
1477        {
1478                                $this->_report_error('property elements with rdf:parseType do not allow property attributes');
1479            return;
1480        }
1481
1482        if(  $attribute_value == RDF_PARSE_TYPE_RESOURCE )
1483        {
1484            $this->_generate_anonymous_uri( $buffer );
1485            // since we are sure that this is now a resource property we can report it
1486            $this->_report_statement(
1487                $this->rdf_parser['top']['parent']['subject_type'],
1488                $this->rdf_parser['top']['parent']['subject'],
1489                $this->rdf_parser['top']['predicate'],
1490                0,
1491                RDF_OBJECT_TYPE_BNODE,
1492                $buffer,
1493                '',
1494                $this->rdf_parser['top']['parent']['bag_id'],
1495                $this->rdf_parser['top']['parent']['statements'],
1496                                $this->rdf_parser['top']['statement_id'],
1497                                $datatype );
1498
1499            $this->_push_element( );
1500
1501            $this->rdf_parser['top']['state'] = IN_PROPERTY_PARSE_TYPE_RESOURCE;
1502            $this->rdf_parser['top']['subject_type'] = RDF_SUBJECT_TYPE_BNODE;
1503            $this->rdf_parser['top']['subject']=$buffer;
1504            $this->rdf_parser['top']['bag_id']='';
1505                        $this->rdf_parser['top']['datatype']= $datatype;
1506
1507        }
1508        elseif (  $attribute_value == RDF_PARSE_TYPE_LITERAL )
1509        {
1510                $this->rdf_parser['top']['state'] = IN_PROPERTY_PARSE_TYPE_LITERAL;
1511                $this->rdf_parser['top']['datatype']= RDF_NAMESPACE_URI .RDF_XMLLITERAL;
1512                $this->rdf_parser['xml_literal']['buffer'] = '';
1513                $this->rdf_parser['xml_literal']['depth'] = 0;
1514        }
1515                elseif ($attribute_value == RDF_PARSE_TYPE_COLLECTION)
1516                {
1517                        $this->_generate_anonymous_uri( $buffer );
1518            $this->_report_statement(
1519                $this->rdf_parser['top']['parent']['subject_type'],
1520                $this->rdf_parser['top']['parent']['subject'],
1521                $this->rdf_parser['top']['predicate'],
1522                0,
1523                RDF_OBJECT_TYPE_BNODE,
1524                $buffer,
1525                '',
1526                $this->rdf_parser['top']['parent']['bag_id'],
1527                $this->rdf_parser['top']['parent']['statements'],
1528                                $this->rdf_parser['top']['statement_id'],
1529                                $datatype );
1530
1531                        $this->rdf_parser['top']['state'] = IN_PROPERTY_PARSE_TYPE_COLLECTION;
1532                        $this->rdf_parser['top']['collection']['first_blank_node_id'] = $buffer;
1533                }
1534
1535        else
1536        {
1537
1538                        $this->_report_statement(
1539                $this->rdf_parser['top']['parent']['subject_type'],
1540                $this->rdf_parser['top']['parent']['subject'],
1541                $this->rdf_parser['top']['predicate'],
1542                0,
1543                RDF_OBJECT_TYPE_XML,
1544                '',
1545                '',
1546                $this->rdf_parser['top']['parent']['bag_id'],
1547                $this->rdf_parser['top']['parent']['statements'],
1548                                $this->rdf_parser['top']['statement_id'],
1549                        $datatype );
1550
1551            $this->rdf_parser['top']['state'] = IN_PROPERTY_PARSE_TYPE_LITERAL;
1552        }
1553    }
1554    else if( $resource !== NULL || $bag_id || $this->rdf_parser['top']['has_property_attributes'] )
1555        {
1556        if( $resource !== NULL )
1557        {
1558            $subject_type = RDF_SUBJECT_TYPE_URI;
1559                        $this->_resolve_uri_reference( $this->rdf_get_base(), $resource, $buffer );
1560                $object_type=RDF_OBJECT_TYPE_RESOURCE;
1561        }
1562        else
1563        {
1564                        $subject_type = RDF_SUBJECT_TYPE_BNODE;
1565            $this->_generate_anonymous_uri( $buffer );
1566            $object_type=RDF_OBJECT_TYPE_BNODE;
1567        }
1568        $this->rdf_parser['top']['state'] = IN_PROPERTY_EMPTY_RESOURCE;
1569
1570        // since we are sure that this is now a resource property we can report it.
1571                $this->_report_statement(
1572            $this->rdf_parser['top']['parent']['subject_type'],
1573            $this->rdf_parser['top']['parent']['subject'],
1574            $this->rdf_parser['top']['predicate'],
1575            $this->rdf_parser['top']['ordinal'],
1576            $object_type,
1577            $buffer,
1578            '',
1579            $this->rdf_parser['top']['parent']['bag_id'],
1580            $this->rdf_parser['top']['parent']['statements'],
1581                        $this->rdf_parser['top']['statement_id'],
1582                        $datatype ); // should we allow IDs?
1583
1584        if( $bag_id )
1585        {
1586            $this->_resolve_id( $bag_id, $buffer );
1587            $this->rdf_parser['top']['bag_id']=$buffer;
1588        }
1589
1590        if( $this->rdf_parser['top']['has_property_attributes'] )
1591        {
1592            $this->_handle_property_attributes(
1593                $subject_type,
1594                $buffer,
1595                $attributes,
1596                $this->rdf_parser['top']['xml_lang'],
1597                $this->rdf_parser['top']['bag_id'],
1598                $this->rdf_parser['top']['statements'] );
1599        }
1600    }
1601}
1602
1603/**
1604   * @param string &$namespace_uri
1605   * @param string &$local_name
1606   * @param string &$attributes
1607   * @access    private
1608*/
1609function _handle_collection_element(&$namespace_uri, &$local_name, &$attributes)
1610{
1611        $aux2=Array();
1612    foreach($attributes as $atkey=>$atvalue) {
1613      $aux2[]=$atkey;
1614      $aux2[]=$atvalue;
1615    }
1616    $attributes=$aux2;
1617/* collection construction site
1618// old:
1619        if (   ($namespace_uri == RDF_NAMESPACE_URI || $namespace_uri == '')
1620            && ($local_name == RDF_DESCRIPTION || $local_name == RDF_LI) )
1621        {
1622                for( $i = 0; isset($attributes[$i]); $i += 2 )
1623        {
1624                        $this->_split_name(
1625                $attributes[ $i ],
1626                $attribute,
1627                $attribute_namespace_uri,
1628                $attribute_local_name );
1629
1630                $attribute_value = $attributes[ $i + 1 ];
1631
1632                if( $attribute_namespace_uri == '' || $attribute_namespace_uri == RDF_NAMESPACE_URI  )
1633                {
1634                    if( $attribute_local_name == RDF_ABOUT ||
1635                        $attribute_local_name == RDF_RESOURCE)
1636                    {
1637                                        $this->rdf_parser['top']['parent']['collection']['object_type'][] = RDF_OBJECT_TYPE_RESOURCE;
1638                    }
1639                    elseif ( $attribute_local_name == RDF_NODEID ) {
1640                        $this->rdf_parser['top']['parent']['collection']['object_type'][] = RDF_OBJECT_TYPE_BNODE;
1641                    }
1642                    $this->rdf_parser['top']['parent']['collection']['object_label'][] = $attribute_value;
1643                }
1644        }
1645        }
1646*/
1647// new
1648
1649                for( $i = 0; isset($attributes[$i]); $i += 2 )
1650        {
1651                        $this->_split_name(
1652                $attributes[ $i ],
1653                $attribute,
1654                $attribute_namespace_uri,
1655                $attribute_local_name );
1656
1657                $attribute_value = $attributes[ $i + 1 ];
1658
1659                if( $attribute_namespace_uri == '' || $attribute_namespace_uri == RDF_NAMESPACE_URI  )
1660                {
1661                        $tmp_subject_type = RDF_SUBJECT_TYPE_URI;
1662                    if( $attribute_local_name == RDF_ABOUT ||
1663                        $attribute_local_name == RDF_RESOURCE)
1664                    {
1665                                        $this->rdf_parser['top']['parent']['collection']['object_type'][] = RDF_OBJECT_TYPE_RESOURCE;
1666                    }
1667                    elseif ( $attribute_local_name == RDF_NODEID ) {
1668                        $this->rdf_parser['top']['parent']['collection']['object_type'][] = RDF_OBJECT_TYPE_BNODE;
1669                        $tmp_subject_type = RDF_SUBJECT_TYPE_BNODE;
1670                    }
1671                    $id_buffer = '';
1672                    $this->_resolve_uri_reference( $this->rdf_get_base(), $attribute_value, $id_buffer );
1673                    $this->rdf_parser['top']['parent']['collection']['object_label'][] = $id_buffer;
1674
1675                if (!(   ($namespace_uri == RDF_NAMESPACE_URI || $namespace_uri == '')
1676                                      && ($local_name == RDF_DESCRIPTION || $local_name == RDF_LI) ))
1677                                   {
1678                                          $this->_report_statement(
1679                                                        $tmp_subject_type,
1680                                                        $id_buffer,
1681                                                        RDF_NAMESPACE_URI.RDF_TYPE,
1682                                                        '',
1683                                                        RDF_OBJECT_TYPE_RESOURCE,
1684                                                        $namespace_uri.$local_name,
1685                                                        '',
1686                                                        '',
1687                                                        '',
1688                                                        '',
1689                                                        '');
1690                                   }
1691                }
1692        }
1693
1694
1695// collection construction site
1696}
1697
1698/**
1699   * @param string &$namespace_uri
1700   * @param string &$local_name
1701   * @param string &$attributes
1702   * @access    private
1703*/
1704function _handle_xml_start_element(&$namespace_uri, &$local_name, &$attributes)
1705{
1706        $aux2=Array();
1707    foreach($attributes as $atkey=>$atvalue) {
1708      $aux2[]=$atkey;
1709      $aux2[]=$atvalue;
1710    }
1711    $attributes=$aux2;
1712
1713    $element = '<' .$this->_join_name_and_declare_prefix($namespace_uri, $local_name);
1714
1715    for( $i = 0; isset($attributes[$i]); $i += 2 )
1716        {
1717                        $this->_split_name(
1718                $attributes[ $i ],
1719                $attribute,
1720                $attribute_namespace_uri,
1721                $attribute_local_name );
1722
1723                $attribute_value = $attributes[ $i + 1 ];
1724
1725                        $element .= ' ' .$this->_join_name_and_declare_prefix($attribute_namespace_uri, $attribute_local_name);
1726                        $element .= '=\"' .$attribute_value .'\"';
1727        }
1728    $element .= '>';
1729
1730    $this->rdf_parser['xml_literal']['buffer'] .= $element;
1731}
1732
1733/**
1734   * @param string $name
1735   * @access    private
1736*/
1737function _handle_xml_end_element($name)
1738{
1739        $buffer='';
1740        $namespace_uri='';
1741    $local_name='';
1742
1743        $this->_split_name(
1744        $name,
1745        $buffer,
1746        $namespace_uri,
1747        $local_name );
1748
1749    $element = '</';
1750
1751        if ($namespace_uri && isset($this->rdf_parser['default_namespace'])
1752            &&$namespace_uri != $this->rdf_parser['default_namespace'])
1753        {
1754                $element .= $this->rdf_parser['namespaces'][$namespace_uri] .':';
1755        }
1756
1757    $element .= $local_name .'>';
1758
1759    $this->rdf_parser['xml_literal']['buffer'] .= $element;
1760    $depth = $this->rdf_parser['xml_literal']['depth']--;
1761
1762    if (isset($this->rdf_parser['xml_literal']['declared_ns']))
1763        foreach ($this->rdf_parser['xml_literal']['declared_ns'] as $prefix => $_depth)
1764    {
1765        if ($depth == $_depth)
1766                unset($this->rdf_parser['xml_literal']['declared_ns'][$prefix]);
1767    }
1768}
1769
1770/**
1771   * @param string $namespace_uri
1772   * @param string $local_name
1773   * @access    private
1774*/
1775function _join_name_and_declare_prefix($namespace_uri, $local_name) {
1776
1777        $name = '';
1778
1779        if ($namespace_uri)
1780        {
1781                if (isset($this->rdf_parser['default_namespace'])
1782                    && $namespace_uri == $this->rdf_parser['default_namespace'])
1783                {
1784                        $name .= $local_name;
1785
1786                        if (!isset($this->rdf_parser['xml_literal']['declared_ns']['_DEFAULT_'])
1787                                && $namespace_uri != XML_NAMESPACE_URI)
1788                        {
1789                                $name .= ' xmlns=' . '\"' .$namespace_uri .'\"';
1790
1791                                $this->rdf_parser['xml_literal']['declared_ns']['_DEFAULT_']
1792                                        = $this->rdf_parser['xml_literal']['depth'];
1793                        }
1794                }
1795                else
1796                {
1797                        $ns_prefix = $this->rdf_parser['namespaces'][$namespace_uri];
1798                        $name .= $ns_prefix .':' .$local_name;
1799
1800                        if (!isset($this->rdf_parser['xml_literal']['declared_ns'][$ns_prefix])
1801                                && $namespace_uri != XML_NAMESPACE_URI)
1802                        {
1803                                $name .= " xmlns:$ns_prefix=" . '\"' .$namespace_uri .'\"';
1804
1805                                $this->rdf_parser['xml_literal']['declared_ns'][$ns_prefix]
1806                                        = $this->rdf_parser['xml_literal']['depth'];
1807                        }
1808                }
1809
1810        }
1811        else
1812                $name .= $local_name;
1813
1814        return $name;
1815
1816}
1817
1818/**
1819  * @access     private
1820*/
1821function _end_collection() {
1822
1823        if (isset($this->rdf_parser['top']['collection']))
1824        {
1825
1826                $subject = $this->rdf_parser['top']['collection']['first_blank_node_id'];
1827
1828                for ($i=0; isset($this->rdf_parser['top']['collection']['object_label'][$i]); $i++)
1829                {
1830
1831                        $this->_report_statement(
1832                                RDF_SUBJECT_TYPE_BNODE,
1833                                $subject,
1834                                RDF_NAMESPACE_URI.RDF_FIRST,
1835                                '',
1836                                $this->rdf_parser['top']['collection']['object_type'][$i],
1837                                $this->rdf_parser['top']['collection']['object_label'][$i],
1838                                '',
1839                                '',
1840                                '',
1841                                '',
1842                                '');
1843
1844                        if (!isset($this->rdf_parser['top']['collection']['object_label'][$i+1]))
1845                        {
1846                                $obj_type_2 = RDF_OBJECT_TYPE_RESOURCE;
1847                                $object_2 = RDF_NAMESPACE_URI.RDF_NIL;
1848                        }
1849                        else
1850                        {
1851                                $obj_type_2= RDF_OBJECT_TYPE_BNODE;
1852                                $this->_generate_anonymous_uri($object_2);
1853                        }
1854
1855
1856                        $this->_report_statement(
1857                                RDF_SUBJECT_TYPE_BNODE,
1858                                $subject,
1859                                RDF_NAMESPACE_URI.RDF_REST,
1860                                '',
1861                                $obj_type_2,
1862                                $object_2,
1863                                '',
1864                                '',
1865                                '',
1866                                '',
1867                                '');
1868
1869                        $subject = $object_2;
1870                }
1871        }
1872}
1873
1874/**
1875   * @param string $parser
1876   * @param string $name
1877   * @param string $attributes
1878   * @access    private
1879*/
1880function _start_element_handler($parser, $name, $attributes )
1881{
1882    $buffer='';
1883
1884    $namespace_uri='';
1885    $local_name='';
1886
1887    $this->_push_element();
1888
1889
1890    $this->_split_name(
1891        $name,
1892        $buffer,
1893        $namespace_uri,
1894        $local_name );
1895
1896    switch( $this->rdf_parser['top']['state'] )
1897    {
1898    case IN_TOP_LEVEL:
1899                // set base_uri, if possible
1900                foreach ($attributes as $key => $value) {
1901                 if($key == XML_NAMESPACE_URI . NAMESPACE_SEPARATOR_CHAR . 'base') {
1902                                        $this->rdf_parser['base_uri'] = $value;
1903                                        $this->rdf_parser['document_base_uri'] = $value;
1904
1905                                        $c = substr($value, strlen($value)-1 ,1);
1906                                        if (!($c=='#' || $c==':' || $c=='/' || $c=="\\"))
1907                                                 $this->rdf_parser['normalized_base_uri'] = $value . '#';
1908                                        else
1909                                                $this->rdf_parser['normalized_base_uri'] = $value;
1910
1911                          }
1912                          elseif ($key == XML_NAMESPACE_URI . NAMESPACE_SEPARATOR_CHAR .'lang')
1913                                $this->rdf_parser['document_xml_lang'] = $value;
1914echo "";
1915                }
1916
1917
1918                if( RDF_NAMESPACE_URI.NAMESPACE_SEPARATOR_STRING.RDF_RDF == $name )
1919        {
1920                        $this->rdf_parser['top']['state'] = IN_RDF;
1921
1922                        break;
1923        }
1924    case IN_RDF:
1925        $this->rdf_parser['top']['state'] = IN_DESCRIPTION;
1926        $this->_handle_resource_element( $namespace_uri, $local_name, $attributes, '' );
1927        break;
1928    case IN_DESCRIPTION:
1929    case IN_PROPERTY_PARSE_TYPE_RESOURCE:
1930                $this->rdf_parser['top']['state'] = IN_PROPERTY_UNKNOWN_OBJECT;
1931        $this->_handle_property_element( $namespace_uri, $local_name, $attributes );
1932        break;
1933        case IN_PROPERTY_PARSE_TYPE_COLLECTION:
1934                $this->_handle_collection_element($namespace_uri, $local_name, $attributes);
1935                break;
1936    case IN_PROPERTY_UNKNOWN_OBJECT:
1937        /* if we're in a property with an unknown object type and we encounter
1938           an element, the object must be a resource, */
1939        $this->rdf_parser['top']['data']='';
1940        $this->rdf_parser['top']['parent']['state'] = IN_PROPERTY_RESOURCE;
1941        $this->rdf_parser['top']['state'] = IN_DESCRIPTION;
1942        $this->_handle_resource_element(
1943            $namespace_uri,
1944            $local_name,
1945            $attributes,
1946            $this->rdf_parser['top']['parent'] );
1947        break;
1948    case IN_PROPERTY_LITERAL:
1949        $this->_report_warning( 'no markup allowed in literals' );
1950        break;
1951    case IN_PROPERTY_PARSE_TYPE_LITERAL:
1952        $this->rdf_parser['top']['state'] = IN_XML;
1953        /* fall through */
1954    case IN_XML:
1955                $this->rdf_parser['xml_literal']['depth']++;
1956                $this->_handle_xml_start_element($namespace_uri, $local_name, $attributes);
1957        break;
1958    case IN_PROPERTY_RESOURCE:
1959        $this->_report_warning(
1960                     'only one element allowed inside a property element' );
1961        break;
1962    case IN_PROPERTY_EMPTY_RESOURCE:
1963        $this->_report_warning(
1964                    'no content allowed in property with rdf:resource, rdf:bagID, or property attributes' );
1965        break;
1966    case IN_UNKNOWN:
1967        break;
1968    }
1969}
1970
1971/**
1972    property elements with text only as content set the state to
1973    IN_PROPERTY_LITERAL. as character data is received from expat,
1974    it is saved in a buffer and reported when the end tag is
1975    received.
1976  * @access     private
1977*/
1978function _end_literal_property()
1979{
1980    if(!isset($this->rdf_parser['top']['statement_id'])) {
1981      $this->rdf_parser['top']['statement_id']='';
1982    }
1983    if(!isset($this->rdf_parser['top']['parent']['subject_type'])) {
1984      $this->rdf_parser['top']['parent']['subject_type']='';
1985    }
1986    if(!isset($this->rdf_parser['top']['parent']['subject'])) {
1987      $this->rdf_parser['top']['parent']['subject']='';
1988    }
1989    if(!isset($this->rdf_parser['top']['parent']['bag_id'])) {
1990      $this->rdf_parser['top']['parent']['bag_id']='';
1991    }
1992    if(!isset($this->rdf_parser['top']['parent']['statements'])) {
1993      $this->rdf_parser['top']['parent']['statements']=0;
1994    }
1995    if(!isset($this->rdf_parser['top']['predicate'])) {
1996      $this->rdf_parser['top']['predicate']='';
1997    }
1998    if(!isset($this->rdf_parser['top']['datatype'])) {
1999      $this->rdf_parser['top']['datatype']='';
2000    }
2001    if(!isset($this->rdf_parser['top']['ordinal'])) {
2002      $this->rdf_parser['top']['ordinal']=0;
2003    }
2004    $this->_report_statement(
2005        $this->rdf_parser['top']['parent']['subject_type'],
2006        $this->rdf_parser['top']['parent']['subject'],
2007        $this->rdf_parser['top']['predicate'],
2008        $this->rdf_parser['top']['ordinal'],
2009        RDF_OBJECT_TYPE_LITERAL,
2010        $this->rdf_parser['top']['data'],
2011        $this->rdf_parser['top']['xml_lang'],
2012        $this->rdf_parser['top']['parent']['bag_id'],
2013        $this->rdf_parser['top']['parent']['statements'],
2014        $this->rdf_parser['top']['statement_id'],
2015                $this->rdf_parser['top']['datatype']);
2016
2017}
2018
2019/**
2020   * @param string $parser
2021   * @param string $name
2022   * @access    private
2023*/
2024function _end_element_handler( $parser, $name )
2025{
2026    switch( $this->rdf_parser['top']['state'] )
2027    {
2028    case IN_TOP_LEVEL:
2029                break;
2030    case IN_XML:
2031                $this->_handle_xml_end_element($name);
2032        break;
2033    case IN_PROPERTY_UNKNOWN_OBJECT:
2034    case IN_PROPERTY_LITERAL:
2035        $this->_end_literal_property( );
2036        break;
2037    case IN_PROPERTY_PARSE_TYPE_RESOURCE:
2038        $this->_pop_element(  );
2039        break;
2040    case IN_PROPERTY_PARSE_TYPE_LITERAL:
2041//              $search =  array((0) => chr(10), (1) => chr(13), (2) => chr(9));
2042//              $replace = array((0) => '\n'   , (1) => '\r'   , (2) => '\t');
2043//              $this->rdf_parser["xml_literal"]["buffer"]
2044//                      = str_replace($search, $replace, $this->rdf_parser["xml_literal"]["buffer"]);
2045
2046                $this->rdf_parser['top']['data'] = $this->rdf_parser['xml_literal']['buffer'];
2047                $this->_end_literal_property();
2048                $this->rdf_parser['xml_literal']['buffer'] = '';
2049
2050        break;
2051        case IN_PROPERTY_PARSE_TYPE_COLLECTION:
2052            $this->_end_collection();
2053                break;
2054    case IN_RDF:
2055    case IN_DESCRIPTION:
2056    case IN_PROPERTY_RESOURCE:
2057    case IN_PROPERTY_EMPTY_RESOURCE:
2058    case IN_UNKNOWN:
2059        break;
2060    }
2061
2062    $this->_pop_element();
2063}
2064
2065/**
2066   * @param string $parser
2067   * @param string $s
2068   * @access    private
2069*/
2070function _character_data_handler( $parser,$s)
2071{
2072    $len=strlen($s);
2073    switch( $this->rdf_parser['top']['state'] )
2074    {
2075    case IN_PROPERTY_LITERAL:
2076    case IN_PROPERTY_UNKNOWN_OBJECT:
2077        if( isset($this->rdf_parser['top']['data']) )
2078        {
2079            $n = strlen( $this->rdf_parser['top']['data'] );
2080            $this->rdf_parser['top']['data'].= $s;
2081
2082        }
2083        else
2084        {
2085            $this->rdf_parser['top']['data']=$s;
2086        }
2087
2088        if( $this->rdf_parser['top']['state'] == IN_PROPERTY_UNKNOWN_OBJECT )
2089        {
2090            /* look for non-whitespace */
2091            for( $i = 0; (( $i < $len ) && (  preg_match("' |\n|\t'",$s{ $i }) )); $i++ );
2092            /* if we found non-whitespace, this is a literal */
2093            if( $i < $len )
2094            {
2095                $this->rdf_parser['top']['state'] = IN_PROPERTY_LITERAL;
2096            }
2097        }
2098
2099        break;
2100    case IN_TOP_LEVEL:
2101        break;
2102    case IN_PROPERTY_PARSE_TYPE_LITERAL:
2103    case IN_XML:
2104        $this->rdf_parser['xml_literal']['buffer'] .= $s;
2105        break;
2106    case IN_RDF:
2107    case IN_DESCRIPTION:
2108    case IN_PROPERTY_RESOURCE:
2109    case IN_PROPERTY_EMPTY_RESOURCE:
2110    case IN_PROPERTY_PARSE_TYPE_RESOURCE:
2111    case IN_UNKNOWN:
2112        break;
2113    }
2114}
2115
2116
2117  /**
2118   * Adds a new statement to the model
2119   * This method is called by generateModel().
2120   *
2121   * @access    private
2122   * @param     string  &$user_data
2123   * @param     string  $subject_type
2124   * @param     string  $subject
2125   * @param     string  $predicate
2126   * @param     string  $ordinal
2127   * @param     string  $object_type
2128   * @param     string  $object
2129   * @param     string  $xml_lang )
2130   * @return    object MemModel
2131   */
2132function add_statement_to_model(
2133        &$user_data,
2134        $subject_type,
2135        $subject,
2136        $predicate,
2137        $ordinal,
2138        $object_type,
2139        $object,
2140        $xml_lang,
2141        $datatype )
2142{
2143
2144        // ParseUnicode
2145        if(UNIC_RDF){
2146                $subject=$this->str2unicode_nfc($subject);
2147                $predicate=$this->str2unicode_nfc($predicate);
2148                $object=$this->str2unicode_nfc($object);
2149        }
2150
2151        //create subject
2152        if ($subject_type == RDF_SUBJECT_TYPE_BNODE)
2153                        $objsub = new BlankNode($subject);
2154            else
2155                        $objsub = new Resource($subject);
2156
2157        // create predicate
2158        $objpred = new Resource($predicate);
2159
2160        // create object
2161        if (($object_type == RDF_OBJECT_TYPE_RESOURCE) || ($object_type == RDF_OBJECT_TYPE_BNODE)) {
2162                        if ($object_type == RDF_OBJECT_TYPE_BNODE)
2163                                        $objobj = new BlankNode($object);
2164                                else
2165                                        $objobj = new Resource($object);
2166        } else {
2167
2168                $objobj = new Literal($object);
2169                if ($datatype != '') {
2170                        $objobj->setDatatype($datatype);
2171                }
2172                elseif ($xml_lang !='') {
2173                        $objobj->setLanguage($xml_lang);
2174                }
2175        }
2176
2177        // create statement
2178        $statement = new Statement($objsub, $objpred, $objobj);
2179
2180        // add statement to model
2181        if(CREATE_MODEL_WITHOUT_DUPLICATES == TRUE){
2182                $this->model->addWithoutDuplicates($statement);
2183        }else
2184                $this->model->add($statement);
2185        }
2186
2187
2188/* public functions */
2189
2190  /**
2191   * Generates a new MemModel from a URI, a file or from memory.
2192   * If you want to parse an RDF document, pass the URI or location in the filesystem
2193   * of the RDF document. You can also pass RDF code direct to the function. If you pass
2194   * RDF code directly to the parser and there is no xml:base included, you should set
2195   * the base URI manually using the optional second parameter $rdfBaseURI.
2196   * Make sure that here are proper namespace declarations in your input document.
2197   *
2198   * @access    public
2199   * @param             string   $base
2200   * @param     boolean  $rdfBaseURI
2201   * @return    object MemModel
2202   */
2203function & generateModel($base,$rdfBaseURI = false, $model = false) {
2204
2205        // Check if $base is a URI or filename or a string containing RDF code.
2206        if (substr(ltrim($base),0 ,1) != '<') {
2207
2208        // $base is URL or filename
2209        $this->model = $model?$model:new MemModel($base);
2210
2211        $input = fopen($base,'r') or die("RDF Parser: Could not open File: $base. Stopped parsing.");
2212        $this->rdf_parser_create( NULL );
2213        $this->rdf_set_base($base);
2214        $done=false;
2215        while(!$done)
2216        {
2217          $buf = fread( $input, 512 );
2218          $done = feof($input);
2219
2220          if ( ! $this->rdf_parse( $buf, feof($input) ) )
2221          {
2222            $err_code = xml_get_error_code( $this->rdf_get_xml_parser());
2223                $line = xml_get_current_line_number($this->rdf_get_xml_parser() );
2224            $errmsg = RDFAPI_ERROR . '(class: parser; method: generateModel): XML-parser-error ' . $err_code .' in Line ' . $line .' of input document.';
2225            trigger_error($errmsg, E_USER_ERROR);
2226          }
2227        }
2228        /* close file. */
2229        fclose( $input );
2230
2231        } else {
2232        // $base is RDF string
2233    $this->model = $model?$model:new MemModel($base);
2234
2235        $this->rdf_parser_create( NULL );
2236
2237        if ($rdfBaseURI!==false)
2238        {
2239                $this->rdf_set_base($rdfBaseURI);
2240        } else
2241        {
2242                $this->rdf_set_base( NULL );
2243        }
2244
2245          if ( ! $this->rdf_parse( $base, TRUE ) )
2246          {
2247            $err_code = xml_get_error_code( $this->rdf_get_xml_parser());
2248                $line = xml_get_current_line_number($this->rdf_get_xml_parser() );
2249            $errmsg = RDFAPI_ERROR . '(class: parser; method: generateModel): XML-parser-error ' . $err_code .' in Line ' . $line .' of input document.';
2250            trigger_error($errmsg, E_USER_ERROR);
2251          }
2252        }
2253        // base_uri could have changed while parsing
2254        $this->model->setBaseURI($this->rdf_parser['base_uri']);
2255
2256        if(isset($this->rdf_parser['namespaces'])){
2257                $this->model->addParsedNamespaces($this->rdf_parser['namespaces']);
2258        }
2259
2260        $this->rdf_parser_free();
2261
2262        return $this->model;
2263
2264}
2265
2266/**
2267 * @param               string   $encoding
2268
2269 * @access      private
2270*/
2271function rdf_parser_create( $encoding )
2272{
2273
2274    $parser = xml_parser_create_ns( $encoding, NAMESPACE_SEPARATOR_CHAR );
2275
2276    xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);
2277    $this->rdf_parser['xml_parser'] = $parser;
2278
2279    xml_set_object($this->rdf_parser['xml_parser'], $this);
2280    xml_set_element_handler( $this->rdf_parser['xml_parser'], '_start_element_handler', '_end_element_handler' );
2281    xml_set_character_data_handler( $this->rdf_parser['xml_parser'], '_character_data_handler' );
2282        xml_set_start_namespace_decl_handler($this->rdf_parser['xml_parser'], '_start_ns_declaration_handler');
2283
2284    return $this->rdf_parser;
2285}
2286
2287/**
2288 * @param       resource        &$parser
2289 * @param   string              $ns_prefix
2290 * @param       string          $ns_uri
2291 * @access      private
2292*/
2293function _start_ns_declaration_handler(&$parser, $ns_prefix, $ns_uri)
2294{
2295        if (!$ns_prefix)
2296                $this->rdf_parser['default_namespace'] = $ns_uri;
2297        else
2298                $this->rdf_parser['namespaces'][$ns_uri] = $ns_prefix;
2299}
2300
2301
2302/**
2303 * @access      private
2304*/
2305function rdf_parser_free( )
2306{
2307    $z=3;
2308
2309    $this->rdf_parser['base_uri']='';
2310        $this->rdf_parser['document_base_uri'] = '';
2311
2312    unset( $this->rdf_parser );
2313}
2314
2315/**
2316   * @param             string   $s
2317   * @param             string   $is_final
2318 * @access      private
2319*/
2320function rdf_parse( $s, $is_final )
2321{
2322    return XML_Parse( $this->rdf_parser['xml_parser'], $s, $is_final );
2323}
2324
2325/**
2326 * @access      private
2327*/
2328function rdf_get_xml_parser()
2329{
2330    return ( $this->rdf_parser['xml_parser']);
2331}
2332
2333/**
2334   * @param             string   $base
2335 * @access      private
2336*/
2337function rdf_set_base($base )
2338{
2339
2340    $this->rdf_parser['base_uri']=$base;
2341
2342        $c = substr($base, strlen($base)-1 ,1);
2343        if (!($c=='#' || $c==':' || $c=='/' || $c=="\\"))
2344                 $this->rdf_parser['normalized_base_uri'] = $base . '#';
2345        else
2346                $this->rdf_parser['normalized_base_uri'] = $base;
2347
2348    return 0;
2349}
2350
2351/**
2352 * @access      private
2353*/
2354function rdf_get_base()
2355{
2356                if ($this->rdf_parser['top']['element_base_uri'])
2357                        return $this->rdf_parser['top']['element_base_uri'];
2358                else
2359                        return $this->rdf_parser['base_uri'];
2360}
2361
2362
2363} // end: rdf_parser
2364
2365?>
Note: See TracBrowser for help on using the repository browser.