Projet

Général

Profil

Paste
Télécharger (4,41 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / feeds_jsonpath_parser / jsonpath-0.8.1.php @ 87dbc3bf

1
<?php
2
/* JSONPath 0.8.1 - XPath for JSON
3
 *
4
 * Copyright (c) 2007 Stefan Goessner (goessner.net)
5
 * Licensed under the MIT (MIT-LICENSE.txt) licence.
6
 */
7

    
8
// API function 
9
function jsonPath($obj, $expr, $args=null) {
10
   $jsonpath = new JsonPath();
11
   $jsonpath->resultType = ($args ? $args['resultType'] : "VALUE");
12
   $x = $jsonpath->normalize($expr);
13
   $jsonpath->obj = $obj;
14
   if ($expr && $obj && ($jsonpath->resultType == "VALUE" || $jsonpath->resultType == "PATH")) {
15
      $jsonpath->trace(preg_replace("/^\\$;/", "", $x), $obj, "$");
16
      if (count($jsonpath->result))
17
         return $jsonpath->result;
18
      else
19
         return false;
20
   }
21
}
22

    
23
// JsonPath class (internal use only)
24
class JsonPath {
25
   var $obj = null;
26
   var $resultType = "Value";
27
   var $result = array();
28
   var $subx = array();
29

    
30
   // normalize path expression
31
   function normalize($x) {
32
      $x = preg_replace_callback("/[\['](\??\(.*?\))[\]']/", array(&$this, "_callback_01"), $x);
33
      $x = preg_replace(array("/'?\.'?|\['?/", "/;;;|;;/", "/;$|'?\]|'$/"),
34
                        array(";", ";..;", ""),
35
                        $x);
36
      $x = preg_replace_callback("/#([0-9]+)/", array(&$this, "_callback_02"), $x);
37
      $this->result = array();  // result array was temporarily used as a buffer ..
38
      return $x;
39
   }
40
   function _callback_01($m) { return "[#".(array_push($this->result, $m[1])-1)."]"; }
41
   function _callback_02($m) { return $this->result[$m[1]]; }
42

    
43
   function asPath($path) {
44
      $x = explode(";", $path);
45
      $p = "$";
46
      for ($i=1,$n=count($x); $i<$n; $i++)
47
         $p .= preg_match("/^[0-9*]+$/", $x[$i]) ? ("[".$x[$i]."]") : ("['".$x[$i]."']");
48
      return $p;
49
   }
50
   function store($p, $v) {
51
      if ($p) array_push($this->result, ($this->resultType == "PATH" ? $this->asPath($p) : $v));
52
      return !!$p;
53
   }
54
   function trace($expr, $val, $path) {
55
      if ($expr) {
56
         $x = explode(";", $expr);
57
         $loc = array_shift($x);
58
         $x = implode(";", $x);
59

    
60
         if (is_array($val) && array_key_exists($loc, $val))
61
            $this->trace($x, $val[$loc], $path.";".$loc);
62
         else if ($loc == "*")
63
            $this->walk($loc, $x, $val, $path, array(&$this, "_callback_03"));
64
         else if ($loc === "..") {
65
            $this->trace($x, $val, $path);
66
            $this->walk($loc, $x, $val, $path, array(&$this, "_callback_04"));
67
         }
68
         else if (preg_match("/,/", $loc)) // [name1,name2,...]
69
            for ($s=preg_split("/'?,'?/", $loc),$i=0,$n=count($s); $i<$n; $i++)
70
                $this->trace($s[$i].";".$x, $val, $path);
71
         else if (preg_match("/^\(.*?\)$/", $loc)) // [(expr)]
72
            $this->trace($this->evalx($loc, $val, substr($path,strrpos($path,";")+1)).";".$x, $val, $path);
73
         else if (preg_match("/^\?\(.*?\)$/", $loc)) // [?(expr)]
74
            $this->walk($loc, $x, $val, $path, array(&$this, "_callback_05"));
75
         else if (preg_match("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", $loc)) // [start:end:step]  phyton slice syntax
76
            $this->slice($loc, $x, $val, $path);
77
      }
78
      else
79
         $this->store($path, $val);
80
   }
81
   function _callback_03($m,$l,$x,$v,$p) { $this->trace($m.";".$x,$v,$p); }
82
   function _callback_04($m,$l,$x,$v,$p) { if (is_array($v[$m])) $this->trace("..;".$x,$v[$m],$p.";".$m); }
83
   function _callback_05($m,$l,$x,$v,$p) { if ($this->evalx(preg_replace("/^\?\((.*?)\)$/","$1",$l),$v[$m])) $this->trace($m.";".$x,$v,$p); }
84

    
85
   function walk($loc, $expr, $val, $path, $f) {
86
      foreach($val as $m => $v)
87
         call_user_func($f, $m, $loc, $expr, $val, $path);
88
   }
89
   function slice($loc, $expr, $v, $path) {
90
      $s = explode(":", preg_replace("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", "$1:$2:$3", $loc));
91
      $len=count($v);
92
      $start=(int)$s[0]?$s[0]:0; 
93
      $end=(int)$s[1]?$s[1]:$len; 
94
      $step=(int)$s[2]?$s[2]:1;
95
      $start = ($start < 0) ? max(0,$start+$len) : min($len,$start);
96
      $end   = ($end < 0)   ? max(0,$end+$len)   : min($len,$end);
97
      for ($i=$start; $i<$end; $i+=$step)
98
         $this->trace($i.";".$expr, $v, $path);
99
   }
100
   function evalx($x, $v, $vname) {
101
      $name = "";
102
      $expr = preg_replace(array("/\\$/","/@/"), array("\$this->obj","\$v"), $x);
103
      $res = eval("\$name = $expr;");
104

    
105
      if ($res === FALSE)
106
         print("(jsonPath) SyntaxError: " . $expr);
107
      else
108
         return $name;
109
   }
110
}
111
?>