Source for file N3Serializer.php

Documentation is available at N3Serializer.php

  1. <?php
  2.  
  3. // ----------------------------------------------------------------------------------
  4. // Class: N3Serializer
  5. // ----------------------------------------------------------------------------------
  6.  
  7. /**
  8. * PHP Notation3 Serializer
  9. *
  10. * This class serialises models to N3 Syntax.
  11. *
  12. * Supported N3 features:
  13. * <ul>
  14. * <li>Using [ ] for blank nodes, or _: if nescessary</li>
  15. * <li>Literal datytype- and xmlLanguageTag support</li>
  16. * </ul>
  17. *
  18. * Un-supported N3 Features include:
  19. * <ul>
  20. * <li>Reification</li>
  21. * </ul>
  22. *
  23. * <b>History:</b>
  24. * <ul>
  25. * <LI>12-06-2004 improved namespace handling added (tobias.gauss@web.de)</LI>
  26. * <li>25-03-2004 Bug in doResource() fixed</li>
  27. * <li>11-27-2003 fixed problems with detection for using [ ] or _: for blank nodes.
  28. * Added constant N3SER_BNODE_SHORT to disable the automatic detection if bnode is referenced elsewhere</li>
  29. * <li>11-19-2003 Support for datatypes and language tags added.</li>
  30. * <li>08-01-2003 Made compatible with new v6 MemModel</li>
  31. * <li>31-07-2003 Function saveAs added. <radol@gmx.de></li>
  32. * <li>07-16-2003 Initial version</li>
  33. * </ul>
  34. *
  35. * TODO: * added namespace prefixes are persisent...
  36. *
  37. * @author Gunnar AA. Grimnes <ggrimnes@csd.abdn.ac.uk>, Daniel Westphal <mail@d-westphal.de>
  38. * @version V0.9.3
  39. * @package syntax
  40. * @access public
  41. ***/
  42.  
  43. define(''MAGIC_STRING'', ''~~~'');
  44.  
  45. class N3Serializer extends Object {
  46.  
  47. var $debug;
  48.  
  49. var $prefixes;
  50.  
  51. var $done; // keeps track of already serialized resources
  52. var $resourcetext;
  53. var $resourcetext_taken;
  54. var $model;
  55. var $res;
  56. var $anon;
  57.  
  58. /**
  59. * Constructor
  60. *
  61. * @access public
  62. */
  63. function N3Serializer() {
  64. $this->debug=FALSE;
  65. }
  66.  
  67.  
  68. /**
  69. * Adds a new namespace prefix to use.
  70. * Unknown namespaces will become ns0, ns1 etc.
  71. * @access public
  72. * @param string $s
  73. * @returns void
  74. ***/
  75.  
  76. function addNSPrefix( $ns, $prefix) {
  77. $this->prefixes[$ns]=$prefix;
  78. }
  79.  
  80. /**
  81. * Serializes a model to N3 syntax.
  82. *
  83. * @param object Model $model
  84. * @return string
  85. * @access public
  86. */
  87. function & serialize(&$m) {
  88.  
  89. if (is_a($m, ''DbModel''))
  90. $m=$m->getMemModel();
  91. $this->reset();
  92. $this->model=$m;
  93. $this->res="";
  94. // copy default namespaces
  95. global $default_prefixes;
  96. foreach($default_prefixes as $prefix => $namespace)
  97. $this->addNSPrefix($namespace,$prefix);
  98. $nps= $this->model->getParsedNamespaces();
  99. if($nps!=false){
  100. foreach($nps as $uri => $prefix){
  101. $this->addNSPrefix($uri,$prefix);
  102. }
  103. }
  104. $namespaces=array();
  105. $count=array();
  106. $resources=array();
  107. foreach ($this->model->triples as $t) {
  108. $s=$t->getSubject();
  109. if ( is_a($s, ''Resource''))
  110. $namespaces[$s->getNamespace()]=1;
  111.  
  112. $p=$t->getPredicate();
  113. if ( is_a($p, ''Resource''))
  114. $namespaces[$p->getNamespace()]=1;
  115.  
  116. $o=$t->getObject();
  117. if ( is_a($o, ''Resource''))
  118. $namespaces[$o->getNamespace()]=1;
  119. $uri=$s->getURI();
  120. if (isset($count[$uri])) {
  121. $count[$uri]++;
  122. } else {
  123. $count[$uri]=0;
  124. $resources[$uri]=$s;
  125. }
  126. }
  127.  
  128. if (!HIDE_ADVERTISE)
  129. $this->res .= ''# Generated by N3Serializer.php from RDF RAP.''.LINEFEED
  130. .''# http://www.wiwiss.fu-berlin.de/suhl/bizer/rdfapi/index.html''
  131. .LINEFEED.LINEFEED;
  132.  
  133. $this->doNamespaces($namespaces);
  134.  
  135. $this->res.=LINEFEED.LINEFEED;
  136.  
  137. arsort($count);
  138. foreach ( $count as $k=>$v) {
  139. $this->doResource($resources[$k]);
  140. // $this->res.=" .\n";
  141. }
  142.  
  143. $c=0;
  144. foreach ( $this->resourcetext as $r=>$t) {
  145.  
  146. if ( preg_match_all(''/''.MAGIC_STRING.''([^ ]+)''.MAGIC_STRING.''/'', $t, $ms, PREG_SET_ORDER)) {
  147.  
  148. foreach($ms as $mseach) {
  149. $rp=$this->resourcetext[$mseach[1]];
  150. $t=preg_replace(''/''.MAGIC_STRING.$mseach[1].MAGIC_STRING.''/'', $rp, $t);
  151. }
  152. }
  153.  
  154. if ($this->debug) $this->res.=$c.'': '';
  155. if ( !( isset($this->resourcetext_taken[$r]) && $this->resourcetext_taken[$r]>0) )
  156. $this->res.=$t.'' .''.LINEFEED;
  157. else if ( $this->debug )
  158. $this->res.='' Skipping : ''.$t.LINEFEED;
  159. $c++;
  160. }
  161.  
  162. // $max=-1111;
  163. // $maxkey="";
  164. // foreach ($count as $k=>$c) {
  165. // if ( $c>$max) { $maxkey=$k; $max=$c; }
  166. // }
  167. // if ($this->debug) {
  168. // print "$maxkey is subject of most triples! ($max) \n";
  169. // }
  170.  
  171. return $this->res;
  172. }
  173.  
  174. /**
  175. * Serializes a model and saves it into a file.
  176. * Returns FALSE if the model couldn''t be saved to the file.
  177. *
  178. * @access public
  179. * @param object MemModel $model
  180. * @param string $filename
  181. * @return boolean
  182. * @access public
  183. */
  184. function saveAs(&$model, $filename) {
  185.  
  186. // serialize model
  187. $n3 = $this->serialize($model);
  188.  
  189. // write serialized model to file
  190. $file_handle = @fopen($filename, ''w'');
  191. if ($file_handle) {
  192. fwrite($file_handle, $n3);
  193. fclose($file_handle);
  194. return TRUE;
  195. }else{
  196. return FALSE;
  197. };
  198. }
  199.  
  200. /* ==================== Private Methods from here ==================== */
  201.  
  202.  
  203. /**
  204. * Readies this object for serializing another model
  205. * @access private
  206. * @param void
  207. * @returns void
  208. ***/
  209. function reset() {
  210. $this->anon=0;
  211. $this->done=array();
  212. $this->resourcetext_taken=array();
  213. $this->resourcetext=array();
  214. $this->res='''';
  215. $this->model=NULL;
  216. unset($this->prefixes);
  217. }
  218.  
  219. /**
  220. * Makes ns0, ns1 etc. prefixes for unknown prefixes.
  221. * Outputs @prefix lines.
  222. * @access private
  223. * @param array $n
  224. * @returns void
  225. ***/
  226. function doNamespaces(&$n) {
  227. $c=0;
  228. foreach ($n as $ns => $nonsense) {
  229. if ( !$ns ) continue;
  230. if ( isset($this->prefixes[$ns]) ) {
  231. $p=$this->prefixes[$ns];
  232. } else {
  233. $p=''ns''.$c;
  234. $this->prefixes[$ns]=$p;
  235. $c++;
  236. }
  237. $this->res.="@prefix $p: <".$ns.''> .''.LINEFEED;
  238. }
  239. }
  240.  
  241. /**
  242. * Fill in $resourcetext for a single resource.
  243. * Will recurse into Objects of triples, but should never look ? (really?)
  244. * @access private
  245. * @param object Resource $r
  246. * @returns boolean
  247. ***/
  248.  
  249. function doResource(&$r) {
  250. // print $r->getURI();
  251.  
  252. $ts=$this->model->find($r, null, null);
  253. if (count($ts->triples)==0) return;
  254. $out="";
  255.  
  256. if ( isset($this->done[$r->getURI()]) && $this->done[$r->getURI()] ) {
  257. if ( is_a($r, ''BlankNode'')) {
  258. if ( $this->resourcetext_taken[$r->getURI()] == 1) {
  259. //Oh bother, we must use the _:blah construct.
  260. $a=$this->resourcetext[$r->getURI()];
  261. $this->resourcetext[$r->getURI()]=''_:anon''.$this->anon;
  262. $this->resourcetext[''_:anon''.$this->anon]=$this->fixAnon($a, ''_:anon''.$this->anon);
  263. $this->resourcetext_taken[$r->getURI()]=2;
  264. $this->anon++;
  265. }
  266.  
  267. }
  268. return false;
  269. }
  270.  
  271. $this->done[$r->getURI()]=TRUE;
  272.  
  273. if ( is_a($r, ''Resource'') ) {
  274.  
  275. if ( is_a($r, ''BlankNode'') ) {
  276.  
  277. //test, if this blanknode is referenced somewhere
  278. $rbn=$this->model->find(null, null, $r);
  279.  
  280. if (count($rbn->triples)>0 | !N3SER_BNODE_SHORT) {
  281. $out.=''_:''.$r->getLabel();
  282. } else {
  283. $out.=''[ '';
  284. };
  285. } else {
  286.  
  287. $this->doURI($r, $out);
  288.  
  289. };
  290. };
  291. usort($ts->triples, ''statementsorter'');
  292. $lastp='''';
  293.  
  294. $out.='' '';
  295.  
  296. foreach ($ts->triples as $t) {
  297. $p=$t->getPredicate();
  298. if ($p == $lastp) {
  299. $out.='' , '';
  300. } else {
  301. if ($lastp!='''') $out.='' ; '';
  302. $this->doURI($p, $out);
  303. $lastp=$p;
  304. }
  305.  
  306. $out.='' '';
  307. $o=$t->getObject();
  308. if ( is_a($o, ''Literal'')) {
  309. $l=$o->getLabel();
  310. if ( strpos($l, LINEFEED) === FALSE ) {
  311. $out.="\"$l\"";
  312. } else {
  313. $out.="\"\"\"$l\"\"\"";
  314. }
  315. if ( $o->getLanguage()!='''' ) {
  316. $out.=''@''.$o->getLanguage();
  317. }
  318. if ( $o->getDatatype()!='''' ) {
  319. $out.=''^^<''.$o->getDatatype().''>'';
  320. }
  321. }
  322. if (is_a($o, ''Resource'')) {
  323. if ($this->debug) print ''Doing object: ''.$o->getURI().LINEFEED;
  324. if ( is_a($o,''BlankNode'')) {
  325.  
  326. // $this->doResource($o);
  327. // $out.=MAGIC_STRING.$o->getURI().MAGIC_STRING; #$this->resourcetext[$o->getURI()];
  328. // $this->resourcetext_taken[$o->getURI()]=1;
  329.  
  330. $out .=''_:''.$o->getLabel();
  331. } else {
  332.  
  333. $this->doURI($o, $out);
  334. }
  335. }
  336. }
  337.  
  338. if (isset($rbn) && !count($rbn->triples)>0 && N3SER_BNODE_SHORT) {$out.='' ] '';};
  339. $this->resourcetext[$r->getURI()]=$out;
  340.  
  341. return TRUE;
  342. }
  343.  
  344. /**
  345. * Format a single URI
  346. * @param string $s
  347. * @access private
  348. * @return void
  349. ***/
  350. function doURI(&$r, &$out) {
  351. if ( $r->getURI()==''http://www.w3.org/1999/02/22-rdf-syntax-ns#type'') {
  352. $out.=''a'';
  353. return;
  354. }
  355. if ($r->getNamespace()!='''') {
  356. $out.=$this->prefixes[$r->getNamespace()].'':''.$r->getLocalName();
  357. } else {
  358. //Will this ever happen?
  359. $out.=$r->getURI();
  360. }
  361. }
  362.  
  363. /**
  364. * Fix the resourcetext for a blanknode where the _: construct was used
  365. * @param string $s
  366. * @param string $a
  367. * @access private
  368. * @return void
  369. ***/
  370. function fixAnon($t,$a) {
  371. $t=preg_replace("/( \] $|^\[ )/", '''', $t);
  372.  
  373. return $a.$t;
  374. }
  375.  
  376. }
  377.  
  378. ?>

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