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

Documentation generated on Fri, 13 Jan 2006 07:49:04 +0100 by phpDocumentor 1.3.0RC4