We Recommend

Pro JavaScript Techniques Pro JavaScript Techniques
Pro JavaScript Techniques is the ultimate JavaScript book for the modern web developer. It provides everything you need to know about modern JavaScript, and shows what JavaScript can do for your web sites. This book doesn't waste any time looking at things you already know, like basic syntax and structures.


Posted By

Roshambo on 09/07/06


Tagged

parse json parser


Versions (?)


Who likes this?

3 people have marked this snippet as a favorite

tylerhall
ange
vali29


JSON Parser


Published in: JavaScript 


A good alternative to eval when security is a concern. From json.org.

  1. /*
  2.   json.js
  3.   2006-12-06
  4.  
  5.   This file adds these methods to JavaScript:
  6.  
  7.   array.toJSONString()
  8.   boolean.toJSONString()
  9.   date.toJSONString()
  10.   number.toJSONString()
  11.   object.toJSONString()
  12.   string.toJSONString()
  13.   These methods produce a JSON text from a JavaScript value.
  14.   It must not contain any cyclical references. Illegal values
  15.   will be excluded.
  16.  
  17.   The default conversion for dates is to an ISO string. You can
  18.   add a toJSONString method to any date object to get a different
  19.   representation.
  20.  
  21.   string.parseJSON(hook)
  22.   This method parses a JSON text to produce an object or
  23.   array. It can throw a SyntaxError exception.
  24.  
  25.   The optional hook parameter is a function which can filter and
  26.   transform the results. It receives each of the values, and its
  27.   return value is used instead. If it returns what it received, then
  28.   structure is not modified.
  29.  
  30.   Example:
  31.  
  32.   // Parse the text. If it contains any "NaN" strings, replace them
  33.   // with the NaN value. All other values are left alone.
  34.  
  35.   myData = text.parseJSON(function (value) {
  36.   if (value === 'NaN') {
  37.   return NaN;
  38.   }
  39.   return value;
  40.   });
  41.  
  42.   It is expected that these methods will formally become part of the
  43.   JavaScript Programming Language in the Fourth Edition of the
  44.   ECMAScript standard in 2007.
  45. */
  46. if (!Object.prototype.toJSONString) {
  47. Array.prototype.toJSONString = function () {
  48. var a = ['['], b, i, l = this.length, v;
  49.  
  50. function p(s) {
  51. if (b) {
  52. a.push(',');
  53. }
  54. a.push(s);
  55. b = true;
  56. }
  57.  
  58. for (i = 0; i < l; i += 1) {
  59. v = this[i];
  60. switch (typeof v) {
  61. case 'undefined':
  62. case 'function':
  63. case 'unknown':
  64. break;
  65. case 'object':
  66. if (v) {
  67. if (typeof v.toJSONString === 'function') {
  68. p(v.toJSONString());
  69. }
  70. } else {
  71. p("null");
  72. }
  73. break;
  74. default:
  75. p(v.toJSONString());
  76. }
  77. }
  78. a.push(']');
  79. return a.join('');
  80. };
  81.  
  82. Boolean.prototype.toJSONString = function () {
  83. return String(this);
  84. };
  85.  
  86. Date.prototype.toJSONString = function () {
  87.  
  88. function f(n) {
  89. return n < 10 ? '0' + n : n;
  90. }
  91.  
  92. return '"' + this.getFullYear() + '-' +
  93. f(this.getMonth() + 1) + '-' +
  94. f(this.getDate()) + 'T' +
  95. f(this.getHours()) + ':' +
  96. f(this.getMinutes()) + ':' +
  97. f(this.getSeconds()) + '"';
  98. };
  99.  
  100. Number.prototype.toJSONString = function () {
  101. return isFinite(this) ? String(this) : "null";
  102. };
  103.  
  104. Object.prototype.toJSONString = function () {
  105. var a = ['{'], b, i, v;
  106.  
  107. function p(s) {
  108. if (b) {
  109. a.push(',');
  110. }
  111. a.push(i.toJSONString(), ':', s);
  112. b = true;
  113. }
  114.  
  115. for (i in this) {
  116. if (this.hasOwnProperty(i)) {
  117. v = this[i];
  118. switch (typeof v) {
  119. case 'undefined':
  120. case 'function':
  121. case 'unknown':
  122. break;
  123. case 'object':
  124. if (v) {
  125. if (typeof v.toJSONString === 'function') {
  126. p(v.toJSONString());
  127. }
  128. } else {
  129. p("null");
  130. }
  131. break;
  132. default:
  133. p(v.toJSONString());
  134. }
  135. }
  136. }
  137. a.push('}');
  138. return a.join('');
  139. };
  140.  
  141.  
  142. (function (s) {
  143. var m = {
  144. '\b': '\\b',
  145. '\t': '\\t',
  146. '\n': '\\n',
  147. '\f': '\\f',
  148. '\r': '\\r',
  149. '"' : '\\"',
  150. '\\': '\\\\'
  151. };
  152.  
  153. s.parseJSON = function (hook) {
  154. try {
  155. if (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.
  156. test(this)) {
  157. var j = eval('(' + this + ')');
  158. if (typeof hook === 'function') {
  159. function walk(v) {
  160. if (v && typeof v === 'object') {
  161. for (var i in v) {
  162. if (v.hasOwnProperty(i)) {
  163. v[i] = walk(v[i]);
  164. }
  165. }
  166. }
  167. return hook(v);
  168. }
  169. return walk(j);
  170. }
  171. return j;
  172. }
  173. } catch (e) {
  174. }
  175. throw new SyntaxError("parseJSON");
  176. };
  177.  
  178. s.toJSONString = function () {
  179. if (/["\\\x00-\x1f]/.test(this)) {
  180. return '"' + this.replace(/([\x00-\x1f\\"])/g, function(a, b) {
  181. var c = m[b];
  182. if (c) {
  183. return c;
  184. }
  185. c = b.charCodeAt();
  186. return '\\u00' +
  187. Math.floor(c / 16).toString(16) +
  188. (c % 16).toString(16);
  189. }) + '"';
  190. }
  191. return '"' + this + '"';
  192. };
  193. })(String.prototype);
  194. }

Report this snippet 

Comments

RSS Icon Subscribe to comments
Posted By: Roshambo on September 7, 2006

This seems to break when being slurped into Textmate via the Snipplr plugin. At a glance, it seems as though some backslashes are disappearing. Compare line 30 before and after being brought into Textmate:

Before: '\\': '\\\\'

After: '\': '\\'

Posted By: Roshambo on September 7, 2006

Nevermind, it turns out I had an old version of the TextMate plugin.

You need to login to post a comment.