`
jueyue
  • 浏览: 195822 次
社区版块
存档分类
最新评论

json 解析

    博客分类:
  • flex
 
阅读更多

看看别人写的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解析库

    PB Json解析库是一种用于处理协议缓冲区(Protocol Buffers,简称PB)与JSON之间相互转换的工具。在软件开发中,尤其是涉及到数据交换时,PB和JSON都扮演着重要的角色。PB是Google推出的一种高效的数据序列化协议,...

    Android 安卓 json解析

    我们将涵盖两种解析方式:本地JSON解析和在线JSON解析。 ### 1. JSON基础知识 JSON是一种文本格式,基于JavaScript语法,但独立于语言。它以键值对的形式存储数据,如`"key": "value"`。数组可以通过方括号`[]`表示...

    JSON 解析 示例代码

    总的来说,理解和掌握JSON解析是现代Web开发的基本技能之一。无论你是前端开发者还是后端开发者,都需要能够有效地读取、解析和生成JSON数据。通过学习和实践,你可以熟练地利用JSON这一强大的工具进行数据交换和...

    自己实现一个简单的JSON解析器

    本着探究 JSON 原理的目的,我将会在这DEMO中实现了一个简单的JSON解析器。由于 JSON 本身比较简单,解析起来也并不复杂。所以如果大家感兴趣的话,在看完本DEMO后,不妨自己动手实现一个 JSON 解析器。

    鬼脸JSON解析小工具forMac

    "鬼脸JSON解析小工具forMac"正是这样一款专为MAC用户设计的实用工具,它的特点在于其独特的鬼脸logo,使得软件在众多工具中具有较高的辨识度。 该工具的主要功能包括: 1. **实时解析**:用户可以直接将包含JSON...

    易语言页面订单json解析

    3. **JSON解析**:易语言提供了JSON解析的库或模块,允许我们解析JSON字符串为易语言的数据结构,如数组或字典。解析过程中,我们需要识别并提取出订单的关键信息,如订单ID、客户信息、商品详情等。 4. **将订单...

    Unity能够在WebGL包使用的json解析.dll

    JSON解析.dll是Unity中用于处理JSON数据的库,它允许开发者将JSON字符串转化为C#对象或者将C#对象转化为JSON字符串。 在Unity与WebGL的结合使用中,由于WebGL的目标是浏览器环境,因此存在一些特定的限制。例如,...

    易语言Json解析模块

    易语言、易Json解析模块、水淼Json 易语言水淼JSON解析模块源码自主解析JSON数据类型,使用树来直观清晰显示出所有结构,辅助程序员快速定位JSON节点提高开发效率。

    C语言精简JSON解析程序,可用于单片机等资源稀缺硬件

    本项目提供的是一款针对C语言的精简JSON解析程序,专为资源有限的硬件环境如单片机设计。 1. **C语言基础** C语言是底层编程的常用工具,具有高效、灵活和资源管理精细等特点,适合于开发对内存和计算能力要求严格...

    JSONObject解析json,C# asp.net JSON解析 com.force.json

    `com.force.json`是一个针对.NET平台的高性能JSON库,由Salesforce公司开发,它提供了快速且内存效率高的JSON解析和生成功能。这个库适用于那些需要高效处理大量JSON数据的应用场景。 首先,我们需要了解JSON的基本...

    JSON解析工具.exe

    适用于json解析,美观直观的观看数据

    json-c 一个用于c语言的json解析库,很强大

    `json-c`就是这样一个专门用于C语言的JSON解析库,它提供了对JSON数据的读取、创建、修改和序列化等功能,使得C程序员可以方便地与JSON格式进行交互。 `json-c`库的核心特性包括: 1. **解析和生成JSON**:`json-c...

    最简单最高效的Json解析

    在Python中,Python的标准库`json`模块提供了非常便捷的JSON解析和序列化功能。要解析一个JSON字符串,我们可以使用`json.loads()`函数。例如: ```python import json json_string = '{"name": "John", "age": 30...

    JSON解析最新版20151017超简JSON效验解析器

    不过,需要注意的是,由于这是2015年的版本,可能不包含最新的JSON解析技术和安全更新,对于最新的JSON规范支持可能存在局限,而且在当前的软件环境下运行可能不稳定或者存在兼容性问题。建议使用最新版本的JSON解析...

    Json解析Gson解析

    本篇文章将深入探讨JSON解析以及Gson库的使用方法。 一、JSON解析基础 JSON是一种独立于语言的数据表示格式,其结构清晰,易于人阅读和编写,同时也容易让机器解析和生成。JSON主要由键值对(key-value pairs)...

    Jason鬼脸mac版-最好用的json解析工具-没有之一

    "Jason鬼脸mac版"就是这样一个专为Mac用户设计的顶级JSON解析工具,它以其强大的功能和友好的用户界面赢得了“最好用”的美誉。 Jason鬼脸(Jason2.app)主要特点包括: 1. **直观展示**:Jason鬼脸提供了清晰的树...

    最全的 json解析JAR包

    本篇将详细介绍JSON解析相关的知识点,并针对"最全的json解析JAR包"进行解析。 1. JSON基本结构: JSON基于JavaScript的一个子集,主要由对象(Object)和数组(Array)两种数据结构组成。对象是键值对的集合,用...

    C#中Json 解析类库,使用dictionary 解析未知字段的对象

    在C#中,当你面对未知结构的JSON数据,即不能预先定义强类型对象时,可以使用`Dictionary, object&gt;`作为载体,将JSON解析为键值对的形式。 以下是使用Json.NET库解析JSON的基本步骤: 1. 引入库:确保项目引用了...

    易语言json解析模块源码【2.0】

    易语言JSON解析模块2.0源码例程程序结合易语言扩展界面支持库和应用接口支持库,调用API函数实现JSON解析、生成、编辑。点评:易语言JSON解析模块2.0源码通过封装JSON类形成稳定强大的json处理核心。资源作者:。...

    delphi_json解析格式化源码

    当我们谈到“delphi_json解析格式化源码”,我们关注的是如何在Delphi环境中处理JSON数据,包括解析JSON字符串为程序可操作的对象,以及将这些对象格式化回JSON文本。 在Delphi中,处理JSON主要依赖于VCL库中的`...

Global site tag (gtag.js) - Google Analytics