1 |
85ad3d82
|
Assos Assos
|
<?php
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
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 |
|
|
|
24 |
|
|
class JsonPath {
|
25 |
|
|
var $obj = null;
|
26 |
|
|
var $resultType = "Value";
|
27 |
|
|
var $result = array();
|
28 |
|
|
var $subx = array();
|
29 |
|
|
|
30 |
|
|
|
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();
|
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))
|
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))
|
72 |
|
|
$this->trace($this->evalx($loc, $val, substr($path,strrpos($path,";")+1)).";".$x, $val, $path);
|
73 |
|
|
else if (preg_match("/^\?\(.*?\)$/", $loc))
|
74 |
|
|
$this->walk($loc, $x, $val, $path, array(&$this, "_callback_05"));
|
75 |
|
|
else if (preg_match("/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/", $loc))
|
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 |
|
|
?> |