看看别人写的json,自己研读一下,顺便做下笔记:
json解析和反解析主要的就是遍历和递归这个思路,
首先是json转成object,思路是:
1.通过chr=src.charCodeAt(nextPos++)这个来一次读取这个json版的String
2.然后通过对这个chr的类型做出不同的返回结果,
3.对这个返回结果做出不同的出来如:
"{" 则开始创建object 直到出现"}"
"[" 开始穿件数组 "]"创建数组结束
4.不论创建对象还是数组,获取下一个value都是通过nextValue()这个同样的方法,
进行处理,也就是进行递归,直到最后一个char
代码如下:
package com.depth.viewer.utils.json { /** * @example ActionScript to use JSONDecoder: * <listing version="3.0"> * var s:String=null; * var jSONDecoder:JSONDecoder = new JSONDecoder(s); * </listing> * **/ public class JSONDecoder { private var value:Object; private var tokenizer:JSONTokenizer; private var token:JSONToken; public function JSONDecoder() { } private var chr:int; private var tok:int; private var src:String; private var lastPos:int; private var nextPos:int; private var cachedChr:Boolean; private var cachedTok:Boolean; public function decode(str:String):* { var val:*; src=str; nextPos=0; cachedChr=false; cachedTok=false; val=nextValue(); if(nextToken()!=0xff)error("Expected end of input found "+flush()); return val; } /** * 获取下一个字符,返回该字符的16进制值 * */ private function nextChar():int { if(cachedChr){ cachedChr=false; return chr; } return chr=src.charCodeAt(nextPos++); } private function nextToken():int { if(cachedTok){ cachedTok=false; return tok; } while(nextChar()==0x20||chr==0x09||isNewline(chr)); /** *这段是判断是不是注释的 */ if(chr==0x2f){//char == "/" if(nextChar()==0x2f){ while(!isNewline(nextChar())){ if(chr==0x00)return tok=0xff; } } else if(chr==0x2a){//char == "*" while(true){ if(nextChar()==0x2a){ if(nextChar()==0x2f)break; else if(chr==0x2a)cachedChr=true; } if(chr==0x00)error("Find /* but cannot find */"); } } else error("Unkown token /"+String.fromCharCode(chr)); return nextToken(); } lastPos=nextPos-1; if(chr==0x22||chr==0x27)return tok=0xfc;// char == " " "||char == " ' " if(chr==0x5d)return tok=0xfb;//char == "]" if(chr==0x5b)return tok=0xfa;//char == "[" if(chr==0x7d)return tok=0xf9;//char == "}" if(chr==0x7b)return tok=0xf8;//char == "{" if(chr==0x2c)return tok=0xf6;//char == "," if(chr==0x3a)return tok=0xf7;//char == ":" if(chr==0x2b)return tok=0xf4;//char == "+" if(chr==0x2d)return tok=0xf5;//char == "-" if(chr==0x00)return tok=0xff;//char == "nul" if(chr==0x2e){//char == "." if(!isDigit(nextChar()))error("Find . but cannot find Digit"); return nextFraction(); } if(isDigit(chr)){ if(chr==0x30){ if(nextChar()!=0x78&&chr!=0x58)cachedChr=true; else{ if(!isHex(nextChar()))error("Find 0x or 0X but cannot find HexDigit"); while(isHex(nextChar())); return cache(0xfe); } } while(true){ if(nextChar()==0x2e)return nextFraction(); if(chr==0x65||chr==0x45)return nextExponent(); if(!isDigit(chr))break; } return cache(0xfe); } if(!isIdentifier(chr))error("Unkown token "+flush()); while(isIdentifier(nextChar())); return cache(0xfd); } private function nextValue():* { if(nextToken()==0xfd){ var str:String=flush(1); if(str=="NaN")return NaN; if(str=="null")return null; if(str=="true")return true; if(str=="false")return false; if(str=="Infinity")return Infinity; if(str=="undefined")return undefined; error("Unkown identifier "+str); } if(tok==0xf8){ var obj:Object={}; if(nextToken()!=0xf9){ cachedTok=true; while (true){ var key:String; if(nextToken()==0xfd)key=flush(1); else if(tok==0xfc)key=nextString(); else error("Unexpected token "+flush()); if(nextToken()==0xf7)obj[key]=nextValue(); else error("Expected token : found "+flush()); if(nextToken()==0xf9)break; if(tok!=0xf6)error("Expected token } or , found "+flush()); } } return obj; } if(tok==0xfa){ var arr:Array=[]; if(nextToken()!=0xfb){ var needComma:Boolean=false; var index:int=0; cachedTok=true; while(true){ if(nextToken()==0xfb)break; if(tok==0xf6){ arr.length=++index; needComma=false; } else if(needComma)error("Expected token ] or , found "+flush()); else{ needComma=true; cachedTok=true; arr[index]=nextValue(); } } } return arr; } if(tok==0xf5)return -nextValue(); if(tok==0xfc)return nextString(); if(tok==0xfe)return Number(flush(1)); if(tok==0xff)error("End of input was encountered"); if(tok!=0xf4)error("Unexpected token "+flush()); return nextValue(); } private function nextString():String { lastPos=nextPos; var str:String=""; var tag:int=chr; while(nextChar()!=tag){ if(chr==0x00||isNewline(chr))error("Unclosed string"); if(chr==0x5c){ str+=flush(1); lastPos+=2; if(nextChar()==0x75||chr==0x78){ var n:int=chr==0x75?4:2; while(n>0&&isHex(nextChar()))n--; if(n==0)str+=String.fromCharCode(parseInt(flush(),16)); else nextPos=--lastPos; } else if(chr==0x6e)str+="\n"; else if(chr==0x72)str+="\r"; else if(chr==0x62)str+="\b"; else if(chr==0x66)str+="\f"; else if(chr==0x74)str+="\t"; else lastPos--; } } return str+flush(1); } /** * 获取这个小数 * */ private function nextFraction():int { while(true){ if(nextChar()==0x65||chr==0x45)return nextExponent(); if(!isDigit(chr))break; } return cache(0xfe); } private function nextExponent():int { if(nextChar()!=0x2b&&chr!=0x2d)cachedChr=true; if(!isDigit(nextChar()))error("Need digit after exponent"); while (isDigit(nextChar())); return cache(0xfe); } private function cache(token:int):int { cachedChr=true; return tok=token; } private function flush(back:int=0):String { return src.substring(lastPos,lastPos=nextPos-back); } private function error(text:String):void { throw new Error(text); } private function isHex(c:int):Boolean { return isDigit(c)||(c>0x60&&c<0x67)||(c>0x40&&c<0x47); } /** * 判断是不是数字 c>0&&c<9 * */ private function isDigit(c:int):Boolean { return c>0x2f&&c<0x3a; } private function isNewline(c:int):Boolean { return c==0x0a||c==0x0d; } private function isIdentifier(c:int):Boolean { if(isDigit(c))return true; if(c>0x60&&c<0x7b)return true; if(c>0x40&&c<0x5b)return true; if(c==0x5f||c==0x24)return true; if(c==0xd7||c==0xf7)return false; if(c<0x00c0||c>0xfaff)return false; if(c>0x00d6&&c<0x00d8)return false; if(c>0x00f6&&c<0x00f8)return false; if(c>0x1fff&&c<0x3040)return false; if(c>0x318f&&c<0x3300)return false; if(c>0x337f&&c<0x3400)return false; if(c>0x3d2d&&c<0x4e00)return false; if(c>0x9fff&&c<0xf900)return false; return true; } private function parseValue() : Object { if (this.token == null) { this.tokenizer.parseError("Unexpected end of input"); } switch(this.token.type) { case JSONTokenType.LEFT_BRACE: { return this.parseObject(); } case JSONTokenType.LEFT_BRACKET: { return this.parseArray(); } case JSONTokenType.STRING: case JSONTokenType.NUMBER: case JSONTokenType.TRUE: case JSONTokenType.FALSE: case JSONTokenType.NULL: { return this.token.value; } default: { this.tokenizer.parseError("Unexpected " + this.token.value); break; } } return null; } } }
下面是把objct转换为json,其实也是同意的思路
首先判断这个object的类型,如null,String等简单类型直接转换
如果是数组:
创建:"[" 然后拼接起来"]"
如果是Object
创建"{" 然后拼接起来"}"
下面是代码
package com.depth.viewer.utils.json { public class JSONEncoder { public function JSONEncoder() { } private var unescapes:Object={"\b":"b","\f":"f","\n":"n","\r":"r","\t":"t"}; private var escapePtn:RegExp=/["\b\f\n\r\t\\]/g;//" private var controlPtn:RegExp=/\x00-\x19/g; public function encode(obj:*):String { var str:String=null; var bool:Boolean=false; if(obj===null)return "null"; if(obj===undefined)return "undefined"; if(obj is String)return encodeString(obj); if(obj is Array){ str="["; for (var i:int=0,j:int=obj["length"];i<j;i++){ bool?(str+=","):(bool=true); str+=encode(obj[i]); } return str+"]"; } if(obj["constructor"]==Object){ str="{"; for (var k:String in obj){ bool?(str+=","):(bool=true); str+=encodeString(k)+":"+encode(obj[k]); } return str+"}"; } return obj; } private function escapeRepl(...args):String { return "\\"+(unescapes[args[0]]||args[0]); } private function controlRepl(...args):String { var hexCode:String=String(args[0]).charCodeAt(0).toString(16); if (hexCode.length==1)hexCode="0"+hexCode; return "\\x"+hexCode; } private function encodeString(str:String):String { str=str.replace(escapePtn,escapeRepl); str=str.replace(controlPtn,controlRepl); return "\""+str+"\""; } } }
相关推荐
PB Json解析库是一种用于处理协议缓冲区(Protocol Buffers,简称PB)与JSON之间相互转换的工具。在软件开发中,尤其是涉及到数据交换时,PB和JSON都扮演着重要的角色。PB是Google推出的一种高效的数据序列化协议,...
我们将涵盖两种解析方式:本地JSON解析和在线JSON解析。 ### 1. JSON基础知识 JSON是一种文本格式,基于JavaScript语法,但独立于语言。它以键值对的形式存储数据,如`"key": "value"`。数组可以通过方括号`[]`表示...
总的来说,理解和掌握JSON解析是现代Web开发的基本技能之一。无论你是前端开发者还是后端开发者,都需要能够有效地读取、解析和生成JSON数据。通过学习和实践,你可以熟练地利用JSON这一强大的工具进行数据交换和...
本着探究 JSON 原理的目的,我将会在这DEMO中实现了一个简单的JSON解析器。由于 JSON 本身比较简单,解析起来也并不复杂。所以如果大家感兴趣的话,在看完本DEMO后,不妨自己动手实现一个 JSON 解析器。
"鬼脸JSON解析小工具forMac"正是这样一款专为MAC用户设计的实用工具,它的特点在于其独特的鬼脸logo,使得软件在众多工具中具有较高的辨识度。 该工具的主要功能包括: 1. **实时解析**:用户可以直接将包含JSON...
3. **JSON解析**:易语言提供了JSON解析的库或模块,允许我们解析JSON字符串为易语言的数据结构,如数组或字典。解析过程中,我们需要识别并提取出订单的关键信息,如订单ID、客户信息、商品详情等。 4. **将订单...
JSON解析.dll是Unity中用于处理JSON数据的库,它允许开发者将JSON字符串转化为C#对象或者将C#对象转化为JSON字符串。 在Unity与WebGL的结合使用中,由于WebGL的目标是浏览器环境,因此存在一些特定的限制。例如,...
易语言、易Json解析模块、水淼Json 易语言水淼JSON解析模块源码自主解析JSON数据类型,使用树来直观清晰显示出所有结构,辅助程序员快速定位JSON节点提高开发效率。
本项目提供的是一款针对C语言的精简JSON解析程序,专为资源有限的硬件环境如单片机设计。 1. **C语言基础** C语言是底层编程的常用工具,具有高效、灵活和资源管理精细等特点,适合于开发对内存和计算能力要求严格...
`com.force.json`是一个针对.NET平台的高性能JSON库,由Salesforce公司开发,它提供了快速且内存效率高的JSON解析和生成功能。这个库适用于那些需要高效处理大量JSON数据的应用场景。 首先,我们需要了解JSON的基本...
适用于json解析,美观直观的观看数据
`json-c`就是这样一个专门用于C语言的JSON解析库,它提供了对JSON数据的读取、创建、修改和序列化等功能,使得C程序员可以方便地与JSON格式进行交互。 `json-c`库的核心特性包括: 1. **解析和生成JSON**:`json-c...
在Python中,Python的标准库`json`模块提供了非常便捷的JSON解析和序列化功能。要解析一个JSON字符串,我们可以使用`json.loads()`函数。例如: ```python import json json_string = '{"name": "John", "age": 30...
不过,需要注意的是,由于这是2015年的版本,可能不包含最新的JSON解析技术和安全更新,对于最新的JSON规范支持可能存在局限,而且在当前的软件环境下运行可能不稳定或者存在兼容性问题。建议使用最新版本的JSON解析...
本篇文章将深入探讨JSON解析以及Gson库的使用方法。 一、JSON解析基础 JSON是一种独立于语言的数据表示格式,其结构清晰,易于人阅读和编写,同时也容易让机器解析和生成。JSON主要由键值对(key-value pairs)...
"Jason鬼脸mac版"就是这样一个专为Mac用户设计的顶级JSON解析工具,它以其强大的功能和友好的用户界面赢得了“最好用”的美誉。 Jason鬼脸(Jason2.app)主要特点包括: 1. **直观展示**:Jason鬼脸提供了清晰的树...
本篇将详细介绍JSON解析相关的知识点,并针对"最全的json解析JAR包"进行解析。 1. JSON基本结构: JSON基于JavaScript的一个子集,主要由对象(Object)和数组(Array)两种数据结构组成。对象是键值对的集合,用...
在C#中,当你面对未知结构的JSON数据,即不能预先定义强类型对象时,可以使用`Dictionary, object>`作为载体,将JSON解析为键值对的形式。 以下是使用Json.NET库解析JSON的基本步骤: 1. 引入库:确保项目引用了...
易语言JSON解析模块2.0源码例程程序结合易语言扩展界面支持库和应用接口支持库,调用API函数实现JSON解析、生成、编辑。点评:易语言JSON解析模块2.0源码通过封装JSON类形成稳定强大的json处理核心。资源作者:。...
当我们谈到“delphi_json解析格式化源码”,我们关注的是如何在Delphi环境中处理JSON数据,包括解析JSON字符串为程序可操作的对象,以及将这些对象格式化回JSON文本。 在Delphi中,处理JSON主要依赖于VCL库中的`...