Source for file RdfParser.php

Documentation is available at RdfParser.php

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

Documentation generated on Fri, 1 Jun 2007 16:50:45 +0200 by phpDocumentor 1.3.2