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

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