JsonSchema使用详解
JSON Schema是一个用于验证JSON数据结构的强大工具, 我查看并学习了JSON Schema的官方文档, 做了详细的记录, 分享一下。
我们可以使用JSON Schema在后续做接口测试中做详细的数据值的校验, 数据类型校验, json数据结构的校验。
jsonschema用以标注和验证JSON文档的元数据的文档
官方文档地址jsonschema
简单实例
有一个简单的json数据, 根据json数据格式编写jsonschema, 然后校验json数据每个字段是否是规定类型。
type关键字
type关键字是json模式的基础, 指定架构的数据类型。
JSON Schema的核心定义了以下基本类型:
- string
- Numeric types
- object
- array
- boolean
- null
这些类型在Python中对应的类型如下, 下表将JavaScript类型的名称映射到Python的相关类型:
| JavaScript | Python |
| string | string |
| number | int/float |
| object | dict |
| array | list |
| boolean | bool |
| null | none |
type关键字可以是一个字符串或数组:
- 如果它是一个字符串, 那么它是上面一个基本能类型的名称
- 如果它是一个数组, 它必须是一个字符串数组, 其中每个字符串是其中一个基本类型的名称, 每个元素都是唯一的。在这种情况下, 如果json代码段与任何给定类型匹配,则改代码段有效。
以下做个type关键字的简单示例:
{“type”: “number”}
定义某个字段类型是number, 如果是 40, 43.0这样是校验通过的
如果是”43”, 包含数字的字符串这样是无法校验通过的.
{“type”: [“number”, ‘string’]}
定义某个字段类型是number或string中一种
如果是43, 或者 “我和你” 这样是校验通过的
如果是[43, “我和你”], 这样是不通过的, 因为不接受结构化数据类型。
object关键字
在Python中, 对象对应的类型是dict类型。
属性 properties
使用properties关键字定义对象上的属性(键值对)。
例如, 我们要为由数字, 街道名称和街道类型组成的地址定义一个简单的模式
必需属性
默认情况下,properties不需要由关键字定义的属性。但是,可以使用required关键字提供所需属性的列表。
required关键字接受一个或多个字符串的数组。每个字符串必须是唯一的。
在以下定义用户记录的示例模式中,我们要求每个用户都有一个名称和电子邮件地址,但我们不介意他们是否提供了他们的地址或电话号码:
大小
可以使用minProperties和maxProperties关键字限制对象上的属性数 。这些中的每一个都必须是非负整数。
数组属性
数组用于有序元素。
在Python中, array类似于 list或tuple类型,具体取决于用法。
例如: [1,2,3,4,5]
[2, ‘dd’]
items
数组的元素可能是任何东西, 但是,根据某些模式验证数组的项通常很有用。这里使用items和additionalItems关键字完成。
在JSON中, 通常使用两种方式的数据
- 列表验证: 任意长度的序列, 其中每个元素匹配相同的模式
- 元组验证: 一个固定长度的序列,其中每个项目可能具有不同的模式, 在此用法中, 每个项目的索引(位置)对于如何解释值是有意义的,例如Python的tuple。
List validation
列表验证对于任意长度的数组非常有用, 其中每个项都匹配相同的模式, 对于此类数组, 将items关键字设置为单个模式, 用该模式来验证数组中的所有项。
注意: 这时items是单个模式, additionalItems关键字没有意义, 不应该使用它。
例如下面的事例中我们定义数组中每个项都是一个数字
如果是[1,2,3,4,5], pass
如果是[1,2,3,’5’, 6] , false
如果是[], pass
Tuple validation
当数组是项目集合时, 就需要元组验证。其中每个项目都有不同的模式, 并且每个项目的序数索引是有意义的。
例如: 街道地址这样表示
1600 Pennsylvania Avenue NW
就有4中type
[number, streent_name, street_type, direction]
每个字段都有不同的架构
- number: 地址编号, 必须是数字
- street_name: 街道的名称, 必须是字符串
- street_type: 街道的类型, 应该是一组固定值的字符串
- direction: 地址的位置, 应该是来自不同值集的字符串
为此我们将items关键字设置成一个数组, 其中每个项目都是一个与文档数组的每个索引相对应的模式, 也就是一个数组, 第一个元素模式验证输入数组的第一个元素. 第二个元素模式验证输入数组的第二个元素, 等等
示例:
如果是[1600, “宾夕法尼亚”, ‘Street’, “NW”], pass
如果是[10,’等等’, ‘等等’], false
并且在默认情况下, 添加其他项目也可以:
[ 1600 , “宾夕法尼亚州” , “Street” , “NW” , “华盛顿” ]
additionalItems关键字控制是否有效有超出了在架构中定义的数组的其他项目,如果设置为false, 则会不允许数组中的额外项。
长度
可以使用minItems和 maxItems关键字指定数组的长度。每个关键字的值必须是非负数。无论是进行List验证还是Tuple验证,这些关键字都有效。
示例:
唯一性
使用uniqueItems关键字设置为true, 则数组中的每个项都是唯一的。
通用关键字
元数据
json模式包含几个关键字, title, description和default, 不严格用来校验格式,但用来描述模式的一部分。
在title和description管家你必须是字符串
枚举值
enum关键字用于限制值, 以一个固定的一组值, 它必须是一个必须包含一个元素的数组,其中每个元素都是唯一的。
{
‘type’ : ‘string’,
‘enum’: [‘red’, ‘green’]
}
如果检验字段的值在枚举中是通过的, 如果不是无法校验通过。
组合模式
JSON Schema包含一些用于将模式组合在一起的关键字,这并不意味着组合来自多个文件或JSON树的模式, 尽管这些工具有助于实现这一点,并在结构化复杂模式中进行了描述。
例如, 在以下的模式, anyOf关键字用于表示给定值可能对任何给定的子模式有效。第一个子模式需要一个最大长度为5的字符串。第二个子模式需要一个最小值为0的数字。只要一个值对这些模式中的任何一个进行验证,它就被认为整个组合模式有效。
{ ‘anyOf’: [ {‘type’: ‘string’, ‘maxLength’: 5}, {‘type’:’string’, ‘minimum’: 0 }]}
用于组合模式的关键字是:
- allOf: 必须对所有子模式有效
- anyOf: 必须对任何子模式有效(一个或多个)
- oneOf: 必须仅对其中一个子模式有效
anyOf
要进行验证anyOf,给定数据必须对任何(一个或多个)给定子模式有效。
如果是 “您好”, pass
如果是 33, pass
如果是 [‘ddd’, 33], false
oneOf
要进行验证oneOf,给定数据必须仅对其中一个给定子模式有效。
如果是5的倍数, pass
如果是3的倍数, pass
如果是5和3的倍数, false
allOf
要进行验证allOf,给定数据必须对所有给定的子模式有效。
$schema关键字
该$schema关键字用于声明JSON片段实际上是JSON模式的一部分。它还声明了针对该模式编写的JSON Schema标准的哪个版本。
建议所有JSON模式都有一个$schema条目,该条目必须位于根目录下。因此,大多数情况下,您需要在架构的根目录下:
“$ schema” : “http://json-schema.org/schema#”
正则表达式
该模式和模式属性关键字使用正则表达式来表示约束。使用的正则表达式语法来自JavaScript(具体为ECMA 262)。但是,并未广泛支持该完整语法,因此建议您坚持使用下述语法的子集。
- 单个unicode字符(下面的特殊字符除外)与自身匹配。
- ^:仅匹配字符串的开头。
- $:仅匹配字符串的末尾。
- (…):将一系列正则表达式分组到单个正则表达式中。
- |:匹配|符号前面或后面的正则表达式。
- [abc]:匹配方括号内的任何字符。
- [a-z]:匹配字符范围。
- [^abc]:匹配未列出的任何字符。
- [^a-z]:匹配范围之外的任何字符。
- +:匹配前一个正则表达式的一个或多个重复。
- *:匹配前面正则表达式的零次或多次重复。
- ?:匹配前一个正则表达式的零次或一次重复。
- +?,?,??:的,+和?预选赛都是贪婪的; 它们匹配尽可能多的文本。有时这种行为是不可取的,您希望匹配尽可能少的字符。
- {x}:完全x匹配前面正则表达式的出现次数。
- {x,y}:匹配前面正则表达式的至少x和最y多次出现。
- {x,}:匹配x前面正则表达式的出现次数或更多。
- {x}?,{x,y}?,{x,}?:上述表达式的惰性版本。
示例:
如果是 “555-1212”, pass
如果是“(888)555-1212” , pass
如果是“(888)555-1212分机532” , false
构建复杂的模式
重用
有些模式可能是在几个地方都是通用的, 如果每次都重写会使模式更加冗长,以后更新也会很复杂, 我们可以用重用的方式来做。
例如:
定义客户记录, 每个客户都有可能同时拥有送货地址和账单地址, 地址总是相同的, 有街道地址, 城市, 州名。
定义地址模式:
{
“type” : “object” ,
我们重用上面的模式, 将其放在父模式下, 名为definitions:
然后我们使用$ref关键字从其他地方引用此架构片段, 指向此模块的位置
{ “$ ref” : “#/ definitions / address” }
值 $ref 是一个名为 JSON Pointer的格式的字符串。
‘#’ 引用当前文档, ‘/’ 遍历文档中对象中的键, 因此
“#/ definitions / address” 意味着:
- 转到文档的根目录
- 找到秘钥的值”definitions”
- 在该对象中, 找到键的值”address”
$ref也可以是相对或绝对的URI, 例如:
{ “$ ref” : “definitions.json#/ address” }
JsonSchema使用详解的更多相关文章
- Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解
Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全 Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
随机推荐
- 使用nginx搭建https服务器(转)
最近在研究nginx,整好遇到一个需求就是希望服务器与客户端之间传输内容是加密的,防止中间监听泄露信息,但是去证书服务商那边申请证书又不合算,因为访问服务器的都是内部人士,所以自己给自己颁发证书,忽略 ...
- Memcached的LRU和缓存命中率
缓存命中率 命中:直接从缓存中读取到想要的数据. 未中:缓存中没有想要的数据,还需要到数据库进行一次查询才能读取到想要的数据. 命中率越高,数据库查询的次数就越少. 读取缓存的速度远比数据库查询的速度 ...
- Spring 中的Null-Safety
之前一直在某些代码中看到过使用@Nullable 标注过的注释,当时也没有在意到底是什么意思,所以这篇文章来谈谈Spring中关于Null的那些事. 在Java中不允许让你使用类型表示其null的安全 ...
- ubuntu打开终端多开标签的快捷键是ctrl+ shift+ T 对比ctrl+ alt+ T 另外窗口打开一个终端
ubuntu打开终端多开标签的快捷键是ctrl+ shift+ T 对比ctrl+ alt+ T 另外窗口打开一个终端
- 挑战--asp.net 文件夹上传
今天遇到一个有趣的问题,公司让平安做一个上传文件夹的功能,这个任务具有一定的挑战性哦.上传文件夹,我第一次看到有人这样做,以前都是上传压缩文件,从来就没有见人上传过文件夹,我也从来就没有尝试过.先不讨 ...
- Dockerfile安装KOD可道云
[root@docker01 base2]# cat Dockerfile FROM centos:6.8 RUN yum install openssh-server -y RUN /etc/ini ...
- Hibernate 中的DetachedCriteria。
今天看到项目中在Web层使用DetachedCriteria进行多条件查询操作,如果在web层做持久层操作,事物还存在吗?这是我第一反应,于是乎就去网上查资料了.结果发现即在web层,程序员使用Det ...
- 【JMeter4.0学习(十)】之JMeter函数简单运用以及结合正则表达式提取器
下面来简单的举个栗子: 首先,把函数和正则表达式提取器放在一块来介绍,如下所示: 1.结构完整展示,下面再一步一步创建添加: 2.添加线程组: 3.首先添加HTTP请求1 4.添加结果树后,运行后查看 ...
- e.target与e.currentTarget对比
复制以下代码,即可查看效果 <!DOCTYPE html> <html> <head lang="en"> <meta charset=& ...
- window下php5安装redis扩展 设置自启动服务
最近想在5.6版本的开发环境装一下redis的扩展,结果找了半天都是失效链接,特此做下备份 5.3-5.6 https://pecl.php.net/package/redis/2.2.7/windo ...