diff options
Diffstat (limited to 'includes/js/dojox/jsonPath')
-rw-r--r-- | includes/js/dojox/jsonPath/README | 125 | ||||
-rw-r--r-- | includes/js/dojox/jsonPath/query.js | 163 | ||||
-rw-r--r-- | includes/js/dojox/jsonPath/tests/jsonPath.js | 211 | ||||
-rw-r--r-- | includes/js/dojox/jsonPath/tests/module.js | 12 | ||||
-rw-r--r-- | includes/js/dojox/jsonPath/tests/runTests.html | 9 |
5 files changed, 520 insertions, 0 deletions
diff --git a/includes/js/dojox/jsonPath/README b/includes/js/dojox/jsonPath/README new file mode 100644 index 0000000..2da2b31 --- /dev/null +++ b/includes/js/dojox/jsonPath/README @@ -0,0 +1,125 @@ +------------------------------------------------------------------------------- +dojox.jsonPath +------------------------------------------------------------------------------- +Version 1.0 +Release date: 11/14/2007 +------------------------------------------------------------------------------- +Project state: beta +------------------------------------------------------------------------------- +Project authors + Dustin Machi + Kris Zyp +------------------------------------------------------------------------------- +Project description + +jsonPath is a query system similar in idea to xpath, but for use against +javascript objects. This code is a port of the jsonPath code at +http://code.google.com/p/jsonpath/. It was contributed under CLA by Stefan +Goessner. Thanks Stefan! +------------------------------------------------------------------------------- +Dependencies: + +Dojo Core (package loader). +------------------------------------------------------------------------------- +Documentation + +Usage: + +var matches = dojox.jsonPath.query(objectToQuery, jsonPathExpresson) + +Expressions: + + $ The Root Object + @ The current object/element + . or [] The child operator + .. Recursive descent + * all objects + [] subscript operator + [,] Union operator + [start:end:step] array slice operator + ?() applies a filter/script expression + () script expresions + + some examples: + + Given the following test data set: + + var json = + { "store": { + "book": [ + { "category": "reference", + "author": "Nigel Rees", + "title": "Sayings of the Century", + "price": 8.95 + }, + { "category": "fiction", + "author": "Evelyn Waugh", + "title": "Sword of Honour", + "price": 12.99 + }, + { "category": "fiction", + "author": "Herman Melville", + "title": "Moby Dick", + "isbn": "0-553-21311-3", + "price": 8.99 + }, + { "category": "fiction", + "author": "J. R. R. Tolkien", + "title": "The Lord of the Rings", + "isbn": "0-395-19395-8", + "price": 22.99 + } + ], + "bicycle": { + "color": "red", + "price": 19.95 + } + } + }; + + Here are some example queries and their output: + + $.store.book[*].author + ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] + + $..author + ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] + + $.store.* + [[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],{"color":"red","price":19.95}] + + $.store..price + [8.95,12.99,8.99,22.99,19.95] + + $..book[(@.length-1)] + [{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}] + + $..book[-1] + [{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}] + + $..book[0,1] + [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}] + + $..book[:2] + [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}] + + $..book[?(@.isbn)] + [{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}] + + $..book[?(@.price<10)] + [{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}] + + $..* + [{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],"bicycle":{"color":"red","price":19.95}},[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],{"color":"red","price":19.95},{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99},"reference","Nigel Rees","Sayings of the Century",8.95,"fiction","Evelyn Waugh","Sword of Honour",12.99,"fiction","Herman Melville","Moby Dick","0-553-21311-3",8.99,"fiction","J. R. R. Tolkien","The Lord of the Rings","0-395-19395-8",22.99,"red",19.95] + + +------------------------------------------------------------------------------- +Installation instructions + +Grab the following from the Dojo SVN Repository: +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/jsonPath + +Install into the following directory structure: +/dojox/jsonPath/ + +...which should be at the same level as your Dojo checkout. diff --git a/includes/js/dojox/jsonPath/query.js b/includes/js/dojox/jsonPath/query.js new file mode 100644 index 0000000..4e24309 --- /dev/null +++ b/includes/js/dojox/jsonPath/query.js @@ -0,0 +1,163 @@ +if(!dojo._hasResource["dojox.jsonPath.query"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.jsonPath.query"] = true; +dojo.provide("dojox.jsonPath.query"); + +dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){ + // summaRy + // Perform jsonPath query `expr` on javascript object or json string `obj` + // obj - object || json string to perform query on + // expr - jsonPath expression (string) to be evaluated + // arg - {}special arugments. + // resultType: "VALUE"||"BOTH"||"PATH"} (defaults to value) + // evalType: "RESULT"||"ITEM"} (defaults to ?) + + var re = dojox.jsonPath._regularExpressions; + if (!arg){arg={};} + + var strs = []; + function _str(i){ return strs[i];} + var acc; + if (arg.resultType == "PATH" && arg.evalType == "RESULT") throw Error("RESULT based evaluation not supported with PATH based results"); + var P = { + resultType: arg.resultType || "VALUE", + normalize: function(expr){ + var subx = []; + expr = expr.replace(/'([^']|'')*'/g, function(t){return "_str("+(strs.push(eval(t))-1)+")";}); + var ll = -1; + while(ll!=subx.length){ + ll=subx.length;//TODO: Do expression syntax checking + expr = expr.replace(/(\??\([^\(\)]*\))/g, function($0){return "#"+(subx.push($0)-1);}); + } + expr = expr.replace(/[\['](#[0-9]+)[\]']/g,'[$1]') + .replace(/'?\.'?|\['?/g, ";") + .replace(/;;;|;;/g, ";..;") + .replace(/;$|'?\]|'$/g, ""); + ll = -1; + while(ll!=expr){ + ll=expr; + expr = expr.replace(/#([0-9]+)/g, function($0,$1){return subx[$1];}); + } + return expr.split(";"); + }, + asPaths: function(paths){ + for (var j=0;j<paths.length;j++){ + var p = "$"; + var x= paths[j]; + for (var i=1,n=x.length; i<n; i++) + p += /^[0-9*]+$/.test(x[i]) ? ("["+x[i]+"]") : ("['"+x[i]+"']"); + paths[j]=p; + } + return paths; + }, + exec: function(locs, val, rb){ + var path = ['$']; + var result=rb?val:[val]; + var paths=[path]; + function add(v, p,def){ + if (v && v.hasOwnProperty(p) && P.resultType != "VALUE") paths.push(path.concat([p])); + if (def) + result = v[p]; + else if (v && v.hasOwnProperty(p)) + result.push(v[p]); + } + function desc(v){ + result.push(v); + paths.push(path); + P.walk(v,function(i){ + if (typeof v[i] ==='object') { + var oldPath = path; + path = path.concat(i); + desc(v[i]); + path = oldPath; + } + }); + } + function slice(loc, val){ + if (val instanceof Array){ + var len=val.length, start=0, end=len, step=1; + loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);}); + start = (start < 0) ? Math.max(0,start+len) : Math.min(len,start); + end = (end < 0) ? Math.max(0,end+len) : Math.min(len,end); + for (var i=start; i<end; i+=step) + add(val,i); + } + } + function repStr(str){ + var i=loc.match(/^_str\(([0-9]+)\)$/); + return i?strs[i[1]]:str; + } + function oper(val){ + if (/^\(.*?\)$/.test(loc)) // [(expr)] + add(val, P.eval(loc, val),rb); + else if (loc === "*"){ + P.walk(val, rb && val instanceof Array ? // if it is result based, there is no point to just return the same array + function(i){P.walk(val[i],function(j){ add(val[i],j); })} : + function(i){ add(val,i); }); + } + else if (loc === "..") + desc(val); + else if (/,/.test(loc)){ // [name1,name2,...] + for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++) + add(val,repStr(s[i])); + } + else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)] + P.walk(val, function(i){ if (P.eval(loc.replace(/^\?\((.*?)\)$/,"$1"),val[i])) add(val,i); }); + else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step] python slice syntax + slice(loc, val); + else { + loc=repStr(loc); + if (rb && val instanceof Array && !/^[0-9*]+$/.test(loc)) + P.walk(val, function(i){ add(val[i], loc)}); + else + add(val,loc,rb); + } + + } + while (locs.length){ + var loc = locs.shift(); + if ((val = result) === null || val===undefined) return val; + result = []; + var valPaths = paths; + paths = []; + if (rb) + oper(val) + else + P.walk(val,function(i){path=valPaths[i]||path;oper(val[i])}); + } + if (P.resultType == "BOTH"){ + paths = P.asPaths(paths); + var newResult = []; + for (var i =0;i <paths.length;i++) + newResult.push({path:paths[i],value:result[i]}); + return newResult; + } + return P.resultType == "PATH" ? P.asPaths(paths):result; + }, + walk: function(val, f){ + if (val instanceof Array){ + for (var i=0,n=val.length; i<n; i++) + if (i in val) + f(i); + } + else if (typeof val === "object"){ + for (var m in val) + if (val.hasOwnProperty(m)) + f(m); + } + }, + eval: function(x, _v){ + try { return $ && _v && eval(x.replace(/@/g,'_v')); } + catch(e){ throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "_v").replace(/\^/g, "_a")); } + } + }; + + var $ = obj; + if (expr && obj){ + return P.exec(P.normalize(expr).slice(1), obj, arg.evalType == "RESULT"); + } + + return false; + +}; + +} diff --git a/includes/js/dojox/jsonPath/tests/jsonPath.js b/includes/js/dojox/jsonPath/tests/jsonPath.js new file mode 100644 index 0000000..b6f2ee6 --- /dev/null +++ b/includes/js/dojox/jsonPath/tests/jsonPath.js @@ -0,0 +1,211 @@ +if(!dojo._hasResource["dojox.jsonPath.tests.jsonPath"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.jsonPath.tests.jsonPath"] = true; +dojo.provide("dojox.jsonPath.tests.jsonPath"); +dojo.require("dojox.jsonPath"); + + +dojox.jsonPath.tests.error = function(t, d, errData){ + // summary: + // The error callback function to be used for all of the tests. + d.errback(errData); +} + +dojox.jsonPath.tests.testData= { + store: { + "book": [ + { + "category":"reference", + "author":"Nigel Rees", + "title":"Sayings of the Century", + "price":8.95 + }, + { + "category":"fiction", + "author":"Evelyn Waugh", + "title":"Sword of Honour", + "price":12.99 + }, + { + "category":"fiction", + "author":"Herman Melville", + "title":"Moby Dick", + "isbn":"0-553-21311-3", + "price":8.99 + }, + { + "category":"fiction", + "author":"J. R. R. Tolkien", + "title":"The Lord of the Rings", + "isbn":"0-395-19395-8", + "price":22.99 + } + ], + "bicycle": { + "color":"red", + "price":19.95 + } + }, + "symbols":{"@.$;":5} +} + +doh.register("dojox.jsonPath.tests.jsonPath", + [ + { + name: "$.store.book[*].author", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..author", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]'; + doh.assertEqual(success,result); + + } + }, + { + name: "$.store.*", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],{"color":"red","price":19.95}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$.store..price", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[8.95,12.99,8.99,22.99,19.95]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..book[(@.length-1)]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..book[-1:]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..book[0,1]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..book[:2]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..book[?(@.isbn)]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$..book[?(@.price<10)]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "$.symbols[*]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[5]'; + doh.assertEqual(success,result); + } + }, + { + name: "$.symbols['@.$;']", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[5]'; + doh.assertEqual(success,result); + } + }, + { + name: "$.symbols[(@[('@.$;')]?'@.$;':'@.$;')]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, this.name)); + var success = '[5]'; + doh.assertEqual(success,result); + } + }, + { + name: "resultType: 'BOTH' test", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, "$..book[*]",{resultType:"BOTH"})); + var success = dojo.toJson([{"path": "$['store']['book'][0]", "value": {"category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": 8.95}}, {"path": "$['store']['book'][1]", "value": {"category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": 12.99}}, {"path": "$['store']['book'][2]", "value": {"category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": 8.99}}, {"path": "$['store']['book'][3]", "value": {"category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": 22.99}}]); + doh.assertEqual(success,result); + } + }, + { + name: "evalType: 'RESULT' test $.store.book[?(@.price<15)][1:3]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, "$.store.book[?(@.price<15)][1:3]",{evalType:"RESULT"})); + var success = '[{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]'; + doh.assertEqual(success,result); + } + }, + { + name: "evalType: 'RESULT' test $.store.book[1].category", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, "$.store.book[1].category",{evalType:"RESULT"})); + var success = '"fiction"'; + doh.assertEqual(success,result); + } + }, + { + name: "evalType: 'RESULT' test $.store.bicycle", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, "$.store.bicycle",{evalType:"RESULT"})); + var success = '{"color":"red","price":19.95}'; + doh.assertEqual(success,result); + } + }, + { + name: "evalType: 'RESULT' test $.store.book[*]", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, "$.store.book[*]",{evalType:"RESULT"})); + var success = '["reference","Nigel Rees","Sayings of the Century",8.95,"fiction","Evelyn Waugh","Sword of Honour",12.99,"fiction","Herman Melville","Moby Dick","0-553-21311-3",8.99,"fiction","J. R. R. Tolkien","The Lord of the Rings","0-395-19395-8",22.99]'; + doh.assertEqual(success,result); + } + }, + { + name: "evalType: 'RESULT' test $.store.book.category", + runTest: function(t) { + var result = dojo.toJson(dojox.jsonPath.query(dojox.jsonPath.tests.testData, "$.store.book.category",{evalType:"RESULT"})); + var success = '["reference","fiction","fiction","fiction"]'; + doh.assertEqual(success,result); + } + }, + + ] +); + + +} diff --git a/includes/js/dojox/jsonPath/tests/module.js b/includes/js/dojox/jsonPath/tests/module.js new file mode 100644 index 0000000..46a5781 --- /dev/null +++ b/includes/js/dojox/jsonPath/tests/module.js @@ -0,0 +1,12 @@ +if(!dojo._hasResource["dojox.jsonPath.tests.module"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.jsonPath.tests.module"] = true; +dojo.provide("dojox.jsonPath.tests.module"); + +try{ + dojo.require("dojox.jsonPath.tests.jsonPath"); +}catch(e){ + doh.debug(e); +} + + +} diff --git a/includes/js/dojox/jsonPath/tests/runTests.html b/includes/js/dojox/jsonPath/tests/runTests.html new file mode 100644 index 0000000..60a1167 --- /dev/null +++ b/includes/js/dojox/jsonPath/tests/runTests.html @@ -0,0 +1,9 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> +<html> + <head> + <title>Dojox Unit Test Runner</title> + <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.jsonPath.tests.module"></HEAD> + <BODY> + Redirecting to D.O.H runner. + </BODY> +</HTML> |