深入了解 Dojo 扩展库中的 JSON 工具包

IBMdW 发布于 2011/11/24 18:58
阅读 700
收藏 3

简介: XML 的出现,解决了一系列不同平台或不同应用程序之间信息通信的问题。有了 XML,用 Java 实现的应用程序和用 C++ 实现的应用程序之间可以基于同一信息格式(XML)进行通信,人们不用再为跨平台数据交互的问题而烦恼。然而,由于 XML 的数据结构比较完善,所以也相对比较复杂,但是在某些情况下,有些标签和属性名称其实是可以省略的。JSON,一种更加简洁的通用数据结构,它几乎只包括 需要使用的数据,没有任何额外的标签,利用 JSON 做数据交互可以节省更多带宽以提高效率。但是,随着 JSON 越来越流行,我们对于大型的、复杂的 JSON 数据的处理似乎显得比较无能为力,无法实现像 XML 那样的 XPath 快速定位、遍历和变换等等,这种瓶颈在 web 开发中表现的尤为明显,JavaScript 对 JSON 数据的处理接口极为单一。Dojox.JSON - Dojo 的 JSON 工具包,封装了很多对 JSON 数据的处理接口,包括查询定位、引用以及 JSON 格式约束,甚至还有类似于 XPath 的 JSONPath 的快速定位的支持,这篇文章将主要来介绍 Dojox 的 JSON 工具包以及它的一些使用方式和技巧。

简介

JSON 全名:JavaScript Object Notation,是一种轻量级的基于文本的数据交换格式,它源自 JavaScript 这种脚本语言,用于表示简单的数据结构。如果我们抛开 JavaScript 语言单纯地看待 JSON,可以说它是语言无关的一种数据结构,正是由于它的这种特性,它经常被用来作为 XML 的一种“替代品”。

Dojox 的 JSON 工具包简介

Dojox 中的 JSON 工具包主要包括 Dojox.JSON 和 Dojox.JSONPath,其中 JSON 包包含查询定位、schema 定义验证以及引用(ref)等,JSONPath 则主要侧重于模拟 XPath 查询。本文会依次介绍 JSON 和 JSONPath 包中的各种接口以及它的一些使用方式和技巧。

Dojox.JSON.Query 接口集

其实从字面意义上来看,大家想必都知道这就是用于检索 JSON 对象内容的接口,它可以快速定位和快速查询出 JSON 对象中我们需要的内容。我们还是通过几个实例来介绍它的用法吧。

先来看一个 JSON 对象的示例:


清单 1. 目标 JSON 对象
 				 
 dojox.json.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\nRings", 
"isbn":"0-395-19395-8", 
"price":22.99 
 } 
 ], 
"bicycle": { 
"color":"red", 
"price":19.95 
 } 
 }, 
"symbols":{"@.$;":5} 
 }; 

可见,这是个相对比较复杂的 JSON 串。我们可以通过如下的一些方式快速检索到我们要的信息:


清单 2. 检索案例 1
 				 
 var result = dojox.json.query("$.store.book[=author]" ,dojox.json.tests.testData); 
 -- '["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]'; 

这里最关键的就是"$.store.book[=author]"该如何翻译了:

“$”这里表示根节点,即“testData”数据本身。

“$.store.book”表示根节点的直接子节点“store”的直接子节点“book”,它的检索行为和 JavaScript 里面对 JSON 数据的“.”操作行为基本是一致的。

“[=author]”表示 book 节点里面键(key)为“author”的节点值,即只取键为“author”的节点值。所以,返回值应为所有的键为“author”的节点值数组,转化 为字符串即为'["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]'。


清单 3. 检索案例 2
 				 
 var result = dojox.json.query("$..author" ,dojox.json.tests.testData); 
 -- '["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]'; 

“..”操作符(两个点)表示递归查找所有的子节点(包括直接的和间接的子节点)。

所以,这里的返回值应为所有的键为“author”的节点值数组,转化为字符串即为'["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"]'。结果同检索案例 1。


清单 4. 检索案例 3
 				 
 var result = dojox.json.query("$.store.*" ,dojox.json.tests.testData); 
 -- '
 [[{"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\\nRings","isbn":"0-395-19395-8","price":22.99}],
 {"color":"red","price":19.95}]'; 

再来看一个特殊通配符“*”,它表示返回所有值,即这里表示“store”下面的所有属性和值,所以它会返回一系列内容。

接下来我们来看看属性值匹配:


清单 5. 检索案例 4
 				 
 var result = dojox.json.query("$..book[0]?price=22.99" ,dojox.json.tests.testData); 
 -- '[{"category":"fiction","author":"J. R. R. Tolkien",
 "title":"The Lord of the\\nRings","isbn":"0-395-19395-8",
 "price":22.99}]'; 

这种方式属于“[?expression]”方式,它是针对数组对象的过滤,即过滤出数组对象里面满足 expression 的所有元素,这里就是得到数组里面 price 为 22.99 的那个或那几个元素。


清单 6. 检索案例 5
 				 
 var result = dojox.json.query("$..book[0][0,1]" ,dojox.json.tests.testData); 
 -- '[{"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}]'; 

 var result = dojox.json.query("$..book[0][:2]" ,dojox.json.tests.testData); 
 -- '[{"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}]'; 

比较上述两种查询,其实区别就在于“,”号和“:”号,“[0,1]”表示数组中第 0 个和第 1 个的联合数组,它也可以为属性值匹配表达式(expression),而“[:2]”是一个截断操作,即从数组开始(第一个元素)到下标为 2 的元素之前的所有元素,“[:2]”等同于“[0:2]”。可以看出,其实这两个查询的返回值是一样的。


清单 7. 检索案例 6
 				 
 var result = dojox.json.query("$..[^?author~'herman melville']" , 
 dojox.json.tests.testData); 
 -- '[{"category":"fiction","author":"Herman Melville",
 "title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]'; 

这里我们再来看看两个新的通配符,“^”:它表示取出重复,相当于 sql 里面的“distinct”,所以这里在找出最终元素后,会去除返回值中重复的元素。“~”是专门用于匹配字符串的,注意,它不区分大小写。

再来看一个稍微复杂一点的:


清单 8. 检索案例 7
 				 
 var result = dojox.json.query("$..[^?@['author']='Herman*']" , 
 dojox.json.tests.testData); 
 -- '[{"category":"fiction","author":"Herman Melville","title":"Moby Dick",
 "isbn":"0-553-21311-3","price":8.99}]'; 

其实也很简单,“@['author']”就是代表 author 属性,“'Herman*'”用于模糊匹配,所以这里的返回值仍是 author 为“Herman Melville”的那个对象。其实“@”是相当于检索到的当前对象的一个引用,“@['author']”其实也相当于“@.author”。

其实,Dojo 的检索接口还支持传入参数,来看下面一个例子:


清单 9. 检索案例 8
 				 
 var result = dojox.json.query("$..book[0]?author=$1&price=$2" , 
 dojox.json.tests.testData, "Herman Melville", 8.99); 
 -- '[{"category":"fiction","author":"Herman Melville",
 "title":"Moby Dick","isbn":"0-553-21311-3","price":8.99}]'; 

这里可以看到“author=$1&price=$2”中“$1”,“$2”这样的标签,这就是形参,可以在随后的 Query 接口中传入实参:“"Herman Melville", 8.99”。


清单 10. 检索案例 9
 				 
 var result = dojox.json.query("$.store.book[/category][/price][=price]" , 
 dojox.json.tests.testData); 
 -- '[8.95,8.99,12.99,22.99]'; 

 var result = dojox.json.query("$.store.book[\\category,\\price][=price]" , 
 dojox.json.tests.testData); 
 -- '[8.95,22.99,12.99,8.99]'; 

“/”表示升序排序,“\”表示降序排序。第一个例子是“category”和“price”分别排序,所以会以后一个 price 的排序为主,所以结果为:“[8.95,8.99,12.99,22.99]”。而第二个排序为多排序,只是靠前的优先级比较高,即靠前的属性先排序,然 后基于前一个排好序的序列,进行后面的后面的排序。所以结果为“[8.95,22.99,12.99,8.99]”。(这里“8.95”在最前的原因就是 category 先排了一次序,致使 reference 在 fiction 之前)

其实,Dojo 的 Query 接口还支持类似“计算”的功能。


清单 11. 检索案例 10
 				 
 var result = dojox.json.query(
 "$.store.book[\\price][0].price - $.store.book[/price][0].price" , 
 dojox.json.tests.testData); 
 -- 14; 

可以看出,以上为降序排在第一位的 price 值“减去”升序排在第一位的 price,即 22.99 - 8.99 = 14。

Dojox.JSONPath 接口集

这个 JSONPath 接口集的功能其实和之前介绍的 Query 接口相似,只是侧重点不同:Query 接口是建立在自身定义的检索过滤通配符规则之上,而这里的 JSONPath 的侧重点主要是模拟 XPath 来实现一套快速定位和检索的功能。

Query 接口和 JSONPath 接口在使用上其实有很大程度的相似性,它们的检索规则,通配符都比较相近,在 JSONPath 中解释如下:

$ 根元素

@ 当前节点

. or [] 子节点操作符

.. 后代节点

* 所有对象,即通用匹配

[] 属性匹配

[,] 联合处理器

[start🔚step] 数组切割

?() 条件过滤器

() 表达式(属性值匹配等)

其实,与 Query 接口大致相近。我们看几个例子:


清单 12. 目标 JSON 对象(JSONPath)
 				 
 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 
                        } 
                  } 
                }; 

针对于这个 JSON 对象,我们例举出如下输入输出共大家参考:


清单 13. 综合检索
 				 
 $.store.book[*].author 
 -- ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] 


 $.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[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":[{"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}, 
 ............. 

这里我们只是简单的举了几个例子,其中“$..book[(@.length-1)]”表示返回 book 中最后一个元素。“$..*”表示返回根节点下面的所有内容。可见,其用法基本与 Query 相似。

JSONPath 的接口使用方式和 Query 接口也大致相当,见如下:


清单 14. 检索案例 10
 				 
var result = dojox.JSONPath.query(dojox.JSONPath.tests.testData, "$..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}]'

大家可以根据自己的实际需要,选择 Query 或者 JSONPath 包。

Dojox.JSON.ref 接口集

这个接口主要提供了一个可以通过“引用”来构造和解析 JSON 对象,这使得我们可以省去很多 JSON 对象里重复的内容,转而用引用替代;同时,还能够让我们构造更加复杂的 JSON 对象。我们先来看看如下示例代码:


清单 15. 简单的引用
 				 
 var testStr = '{ 
 a:{$ref:"#"}, 
 id:"root", 
 c:{d:"e",f:{$ref:"root.c"}}, 
 b:{$ref:"#.c"}, 
"an array":["a string"], 
"a string":{$ref:"#an array.0"} 
 }'; 

这里大家可以看到一些特殊的标记,我们来一一解释:

{$ref:"#"}:这里代表它就是根对象的引用,也就是说“a:{$ref:"#"}”中“a”的值就是这个 JSON 对象本身(根对象)。

{$ref:"root.c"}:这里表示它是 id 为“root”的对象下面的“c”属性的引用。

{$ref:"#.c"}:其实“#”这里就代表根元素,即就是对象本身。

{$ref:"#an array.0"}:这里“#an array”代表根元素下面的键(key)为“an array”的对象引用。

我们可以通过如下方法将它从字符串转为 JSON 对象:


清单 16. 字符串转 JSON
 				 
 var testStr = '{ 
 a:{$ref:"#"}, 
 id:"root", 
 c:{d:"e",f:{$ref:"root.c"}}, 
 b:{$ref:"#.c"}, 
"an array":["a string"], 
"a string":{$ref:"#an array.0"} 
 }'; 
 var mirrorObj = dojox.json.ref.fromJson(testStr); 
			

转为 JSON 对象(mirrorObj)后,可以了解到,由于该 JSON 字符串中有很多引用,所以可以得出里面的很多相等的关系,见如下代码:


清单 17. 有引用的 JSON 对象
 				 
mirrorObj==mirrorObj.a 
mirrorObj.c==mirrorObj.c.f 
mirrorObj.c==mirrorObj.b 
mirrorObj["a string"]=="a string" 
			

“mirrorObj.a”为“{$ref:"#"}”,所以它就是“mirrorObj”本身。

“mirrorObj.c.f”为“{$ref:"root.c"}”,所以它就是根元素的“c”对象,就是“mirrorObj.c”。

“mirrorObj.b”为“{$ref:"#.c"}”,显然它就是“mirrorObj.c”。

“mirrorObj["a string"]”为“{$ref:"#an array.0"}”,就是根元素的"an array"键值的第 0 个元素,即为"a string"。

再来看一个引用的例子:


清单 18. 关于数组
 				 
var testStr = '[{$ref:1,foo:"bar"},{$ref:2, me:{$ref:2},first:{$ref:1}}]'; 
			

可见这里是一个顶层为数组类型的 JSON 字符串,“$ref:1”指代数字的第 1 个元素(数组的第 0 个)。所以有如下结论:


清单 19. 数组元素的引用
 				 
var mirrorObj = dojox.json.ref.fromJson(testStr); 
mirrorObj[0].foo=="bar" 
mirrorObj[1]==mirrorObj[1].me 
mirrorObj[0]==mirrorObj[1].first 
			

其中“mirrorObj[1].first”为“{$ref:1}”,即为“mirrorObj[0]”。

Dojox.JSON.schema 接口集

其实它主要用于判断一个 JSON 对象是否满足某个定义规则。我们知道每个 XML 都会有一个 DTD 定义,这个 XML 必须满足该 DTD 定义的规则才能算得上是一个合法的 XML。同样,我们的 JSON 也有这种定义。

这种定义的作用非常广泛:如果我们加入了这样的一些预先定义的规则限制,那么,在我们解析 XML 或者 JSON 的时候,可以先验证一下它的合法性,这样我们就不用在读取 XML 或者 JSON 数据时做一些额外的验证或者判断了,因为经过合法性验证的 XML 或者 JSON 必然符合我们的要求(包括数据格式和类型)。在这里我们就基于 Dojox.JSON 包中的 schema 接口来介绍一下 JSON 中的“DTD”。

Dojox 中的“DTD”也是 JSON 格式,参见如下一种定义(schema):


清单 20. 简单的 schema
 				 
 var biggerSchema = { 
  "readonly":true, 
  "type":"object", 
  "properties":{ 
    "name": {"type":"string", 
   length:5, 
       "optional":false}, 
    "tuple":{items:[{"type":"integer"}, 
    {"type":"string"}, 
    {"type":"boolean"}]}, 
    "born" : {"type":["number","string"], 
 //allow for a numeric year, or a full date 
      "format":"date", //format when a string value is used 
      "minimum":1900, //min/max for when a number value is used 
      "maximum":2010 
    }, 
    "gender" : {"type":"string", 
    "enum":["male","female"], 
"options": [{"label":"Male",value:"male"}, 
 {"label":"Female",value:"female"}] 
    }, 
    "address" : {"type":"object", 
    "properties": 
        {"street":{"type":"string"}, 
         "city":{"type":"string"}, 
         "state":{"type":"string"}} 
    } 
  } 
 }; 

我们来看看这个 JSON 格式的 schema:

"readonly":true,代表待验证的 JSON 对象应为只读。

"type":"object",代表待验证的 JSON 对象应为键 - 值对的对象格式(区别于数组)。

"properties",里面包含了该 JSON 对象支持的所有属性的键,以及其对应的值应满足的条件。

"name"中,这里的"type":"string"代表其值应为字符串类型,"optional":false 表示为必须项(键),length:5 表示不能小于 5 个字符。

"tuple"中,这种写法表示它的值为数组类型,第一个为整型,第二个为字符串,第三个为布尔值。

"born"中,"type":["number","string"] 表示它的取值类型可以为数字或者字符串,"format":"date"表示如果值为字符串类型,则会格式化成 Date 类型,如果为数字,则其允许的最小值为 1900,最大值为 2010。

"gender"中,其值的类型须为字符串,"enum":["male","female"] 表示该字符串的值须在"male"和"female"中二者选其一。

"address"中,其实它与"tuple"有点类似,只是这里为对象而不是数组,并且该对象有三个键值"street","city","state",它们的值都必须为字符串类型。

好了,看到这里,我们知道“biggerSchema”定义了一种 JSON 规则,现在我们来看看,如下的两个 JSON 对象是否合法:


清单 21. 简单的 JSON
 				 
 var biggerObj = { 
  "name" : "John Doe", 
  "born" : "1979-03-23T06:26:07Z", 
  "gender" : "male", 
  tuple:[1,"a",false], 
  "address" : {"street":"123 S Main St", 
    "city":"Springfield", 
    "state":"CA"} 
  
 }; 

这里我们看到,如果按照清单 1 中的 schema 来验证,这里"name"为字符,且长度大于 5;"born"为字符串,"gendar"的值符合要求,"tuple"为数组,且数组内容也满足条件,"address"为对象,且其内容也符合要 求,所以该 JSON 对象(biggerObj)是合法的。

如何验证它是否合法呢?这个时候 Dojo 的 JSON 包的 schema 接口就派上用场了:


清单 22. JSON 验证
 				 
 var valid = dojox.json.schema.validate(biggerObj,biggerSchema).valid 
 Console.log(valid)--- true 

通过简单的一个 API,就可以完成复杂的验证工作,对于我们在平时日常 web 开发中可能拿到的所有 JSON 变量,用这种方式做数据检测和验证是最为便捷和安全的,推荐大家多多采用。

再来看看如下的另一个 JSON 对象:


清单 23. 简单的 schema
 				 
 var invalidBiggerObj = { 
  "name" : "John Doe", 
  "born" : false, 
  "gender" : "mal", 
  "address" : {"street":"123 S Main St", 
    "city":"Springfield", 
    "state":"CA"} 
  
 }; 

细心的读者可能已经看到,这里的"gender"的值为"mal",不是定义中说的"male"和"female"其中之一,所以 validate 方法的返回值就是 false。

再来看看如下一种 schema:


清单 24. Disallow schema
 				 
 var schema={ 
 disallow: [{maxLength:4}] 
 } 

这个 schema 看上去很简单,其实它就是定义:如果所验证的对象不超过 4 个字符,就不合法。(注意:schema 不是仅仅只能验证 JSON,它是和任何类型的数据,只不过 JSON 上用的比较广泛),其验证结果可以参考如下代码:


清单 25. 字符串验证
 				 
 dojox.json.schema.validate("hello", schema).valid--- false 
 dojox.json.schema.validate("hi", schema).valid--- true 

可见,"hello"有 5 个字符,超过之前的 4 位({maxLength:4})的限制,所以返回 false,不合法。而"hi"是满足要求的。

还有数字的验证:


清单 26. Decimal schema
 				 
 var schema={ 
 maxDecimal: 4 
 } 

很简单,它就是定义小数位数不能超过 4 位,其验证结果可以参考如下代码:


清单 27. 数字验证
 				 
 dojox.json.schema.validate(4.44, schema).valid--- true 
 dojox.json.schema.validate(4.444444, schema).valid--- false 

Dojo 的 JSON 验证包还可以验证数组:


清单 28. 数组 schema
 				 
 var schema={ 
 items: [{type:"string"},{type:"number"}] 
 }; 

数组有两个元素,第一个为字符串,第二个为数字。其验证结果可以参考如下代码:


清单 29. 数组验证
 				 
 dojox.json.schema.validate(4.44, schema).valid--- true 
 dojox.json.schema.validate([22,22], schema).valid--- false

很显然,"[22, 22]" 均为数字,不合法。

再来看一个简单的验证 schema:


清单 30. 纯类型 schema
 				 
 var schema={ 
 type: ["string", "number"] 
 }; 

这个专门用于验证输入值必须为字符串或数字。其验证结果可以参考如下代码:


清单 31. 纯类型验证
 				 
 dojox.json.schema.validate(22, schema).valid--- true 
 dojox.json.schema.validate("hi", schema).valid--- true 
 dojox.json.schema.validate(null, schema).valid--- false 
 dojox.json.schema.validate({foo:"bar"}, schema).valid--- false 

所以,可以看出,空值和对象在这里都无法通过验证。

再来看一个稍微复杂一点的 schema:


清单 32. 对象 schema
 				 
var schema = {type:[ 
 {type:"object", properties:{name:{type:"string"}, id:{type:"integer"}}, 
 additionalProperties:false}, 
 {type:"object", properties:{brand:{type:"string"}, id:{type:"integer"}}, 
 additionalProperties:false}] 
 }; 

这里它表示,所验证的内容为:两种对象类型任选其一,符合其中一个即可。其验证结果可以参考如下代码:


清单 33. 对象验证
 				 
 1. dojox.json.schema.validate({name:"Bill", id:3}, schema).valid--- true 

 2. dojox.json.schema.validate({brand:"Dojo", id:3}, schema).valid--- true 

 3. dojox.json.schema.validate({foo:"bar"}, schema).valid--- false 

 4. dojox.json.schema.validate({foo:"bar", brand:"Dojo", id:3}, schema).valid--- false 

 5. dojox.json.schema.validate("a string", schema).valid--- false 

"additionalProperties: false" 表示这里不能添加额外属性,任何缺失(示例 3),多余添加(示例 4),以及非对象类型(示例 5)都不合法。

最后大家看看这个 schema:


清单 34. 不合法的 schema
 				 
 var schema = { 
 properties: { foo:"string"} 
 }; 

这其实是一个不合法的 schema,它没有定义 type 为 object,就直接定义其键"foo"必须为字符串,这种写法不符合 schema 的定义规范。

结束语

这篇文章介绍了 Dojo 开发中关于 JSON 的工具包,从查询(Query),引用以及验证三个角度阐述了 JSON 包的主要功能,基于实例源代码,阐述了查询接口,引用接口和定义验证接口的很多初级和高级功能及使用方式等等,同时,也强调了一些不合法的使用方式。这些 工具包的使用可以大大提高我们的开发效率,提高我们代码的质量,我们可以在开发过程中多关注一下,以尽可能多的完善我们的 Web 应用。

文章出处:IBM developerWorks

加载中
0
mallon
mallon
JSON.stringify和JSON.parse足以,没必要搞这么复杂
返回顶部
顶部