python库JsonSchema验证JSON数据结构使用详解

目录
  • 简单实例
  • type关键字
  • object关键字
    • 属性 properties
    • 必需属性
    • 大小
    • 数组属性
    • items
    • List validation
    • Tuple validation
    • 长度
    • 唯一性
  • 通用关键字
    • 元数据
    • 枚举值
  • 组合模式
    • anyOf
    • oneOf
    • allOf
  • $schema关键字
  • 正则表达式
  • 构建复杂的模式
    • 重用

JSON Schema是一个用于验证JSON数据结构的强大工具, 我查看并学习了JSON Schema的官方文档, 做了详细的记录, 分享一下。

我们可以使用JSON Schema在后续做接口测试中做详细的数据值的校验, 数据类型校验, json数据结构的校验。

jsonschema用以标注和验证JSON文档的元数据的文档

官方文档地址jsonschema

简单实例

有一个简单的json数据, 根据json数据格式编写jsonschema, 然后校验json数据每个字段是否是规定类型。

import jsonschema
json_data = [
{
  'pm10': 24,
  'city': '珠海',
  'time': '2016-10-23 13:00:00'
},
{
  'pm10': 24,
  'city': '深圳',
  'time': '2016-10-21 13:00:00'
},
{
  'pm10': '21',
  'city': '广州',
  'time': '2016-10-23 13:00:00'
}
]
json_schema = {
  'type': 'array',
  'items': {
    'type': 'object',
    'properties': {
      'pm10': {
        'type': 'number',
      },
      'city': {
        'type': 'string',
        'enum': ['珠海', '深圳']
      },
      'time': {
        'type': 'string'
      }
    }
  }
}
try:
  jsonschema.validate(json_data, json_schema)
except jsonschema.ValidationError as ex:
  msg = ex
  print(ex)

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关键字定义对象上的属性(键值对)。例如, 我们要为由数字, 街道名称和街道类型组成的地址定义一个简单的模式

{
  “type” : “object” ,
  “properties” : {
    “number” : { “type” : “number” },
    “street_name” : { “type” : “string” },
    “street_type” : {
         “type” : “string” ,
         “enum” : [ “Street” , “Avenue” , “Boulevard” ]
    }
  }
}

必需属性

默认情况下,properties不需要由关键字定义的属性。但是,可以使用required关键字提供所需属性的列表。

required关键字接受一个或多个字符串的数组。每个字符串必须是唯一的。

在以下定义用户记录的示例模式中,我们要求每个用户都有一个名称和电子邮件地址,但我们不介意他们是否提供了他们的地址或电话号码:

{
  “type” : “object” ,
  “properties” : {
    “name” : { “type” : “string” },
    “email” : { “type” : “string” },
    “address” : { “type” : “string” },
    “telephone” : { “type” : “string” }
  },
  “required” : [ “name” , “email”]
}

大小

可以使用minProperties和maxProperties关键字限制对象上的属性数 。这些中的每一个都必须是非负整数。

{
  “type” : “object” ,
  “minProperties” : 2 ,
  “maxProperties” : 3
}

数组属性

数组用于有序元素。

在Python中, array类似于 list或tuple类型,具体取决于用法。

例如: [1,2,3,4,5]

[2, ‘dd’]

items

数组的元素可能是任何东西, 但是,根据某些模式验证数组的项通常很有用。这里使用items和additionalItems关键字完成。

在JSON中, 通常使用两种方式的数据

  • 列表验证: 任意长度的序列, 其中每个元素匹配相同的模式
  • 元组验证: 一个固定长度的序列,其中每个项目可能具有不同的模式, 在此用法中, 每个项目的索引(位置)对于如何解释值是有意义的,例如Python的tuple。

List validation

列表验证对于任意长度的数组非常有用, 其中每个项都匹配相同的模式, 对于此类数组, 将items关键字设置为单个模式, 用该模式来验证数组中的所有项。

注意: 这时items是单个模式, additionalItems关键字没有意义, 不应该使用它。

例如下面的事例中我们定义数组中每个项都是一个数字

{
  “type” : “array” ,
  "items": {
    "type": "number"
  }
}

如果是[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关键字设置成一个数组, 其中每个项目都是一个与文档数组的每个索引相对应的模式, 也就是一个数组, 第一个元素模式验证输入数组的第一个元素. 第二个元素模式验证输入数组的第二个元素, 等等

示例:

{
  “type” : “array” ,
  “items” : [
    {
      “type” : “number”
    },
    {
      “type” : “string”
    },
    {
      “type” : “string” ,
      “enum” : [ “Street” “ , ”Avenue“ , ”Boulevard“ ]
    },
    {
      ”type“ : ”string“ ,
      ”enum“ : [ ”NW“ , ”NE“ , “SW” , “SE” ]
    }
  ]
}

如果是[1600, “宾夕法尼亚”, ‘Street’, “NW”], pass如果是[10,’等等’, ‘等等’], false并且在默认情况下, 添加其他项目也可以:[ 1600 , “宾夕法尼亚州” , “Street” , “NW” , “华盛顿” ]

additionalItems关键字控制是否有效有超出了在架构中定义的数组的其他项目,如果设置为false, 则会不允许数组中的额外项。

长度

可以使用minItems和 maxItems关键字指定数组的长度。每个关键字的值必须是非负数。无论是进行List验证还是Tuple验证,这些关键字都有效。示例:

{
  “type” : “array” ,
  “minItems” : 2 ,
  “maxItems” : 3
}

唯一性

使用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,给定数据必须对任何(一个或多个)给定子模式有效。

{
  “anyOf” : [
    { “type” : “string” },
    { “type” : “number” }
  ]
}

如果是 “您好”, pass如果是 33, pass如果是 [‘ddd’, 33], false

oneOf

要进行验证oneOf,给定数据必须仅对其中一个给定子模式有效。

{
  “oneOf” : [
    { “type” : “number” , “multipleOf” : 5 },
    { “type” : “number” , “multipleOf” : 3 }
  ]  
}

如果是5的倍数, pass如果是3的倍数, pass如果是5和3的倍数, false

allOf

要进行验证allOf,给定数据必须对所有给定的子模式有效。

{
  “allOf” : [
    { “type” : “string” },
    { “maxLength” : 5 }
  ]
}

$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,}?:上述表达式的惰性版本。

示例:

{
  “type” : “string” ,
  “pattern” : “^(\\([0-9] {3} \\))?[0-9]{3}-[0-9] {4} $ “
}

如果是 “555-1212”, pass如果是“(888)555-1212” , pass如果是“(888)555-1212分机532” , false

构建复杂的模式

重用

有些模式可能是在几个地方都是通用的, 如果每次都重写会使模式更加冗长,以后更新也会很复杂, 我们可以用重用的方式来做。例如:定义客户记录, 每个客户都有可能同时拥有送货地址和账单地址, 地址总是相同的, 有街道地址, 城市, 州名。

定义地址模式:

{
  “type” : “object” ,
  “properties” : {
    “street_address” : { “type” : “string” },
    “city” : { “type” : “string” },
    “state” : { “type” : “string” }
  },
  “required” : [ “street_address” , “city” ,“state” ]
}

我们重用上面的模式, 将其放在父模式下, 名为definitions:

{
  “definitions” : {
    “address” : {
      “type” : “object” ,
      “properties” : {
        “street_address” :{“type” :“string”},
        “city” : { “type” : “string” },
        “state” : { “type” : “string” }
      },
    “required” :[“street_address” ,“city”,“州”]
    }
  }
}

然后我们使用$ref关键字从其他地方引用此架构片段, 指向此模块的位置

{ “$ ref” : “#/ definitions / address” }

值 $ref 是一个名为 JSON Pointer的格式的字符串。

‘#’引用当前文档,‘/’遍历文档中对象中的键, 因此

“#/ definitions / address” 意味着:

  • 转到文档的根目录
  • 找到秘钥的值”definitions”
  • 在该对象中, 找到键的值”address”

$ref也可以是相对或绝对的URI, 例如:

{ “$ ref” : “definitions.json#/ address” }

以上就是python库JsonSchema验证JSON数据结构使用详解的详细内容,更多关于JsonSchema验证JSON数据结构的资料请关注我们其它相关文章!

(0)

相关推荐

  • Jackson2的JsonSchema实现java实体类生成json方式

    目录 核心工具类 怎么使用 测试用的实体类 用法 转换结果 除Swagger等文档插件,全网首发,同时支持Json和Xml 核心工具类 Json2Utils.java package com.xxx.demo.common.util; import java.io.IOException; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; im

  • php使用json-schema模块实现json校验示例

    本文实例讲述了php使用json-schema模块实现json校验.分享给大家供大家参考,具体如下: 客户端和服务端的http信息传递,采用json几乎成了标配.json格式简单,易于处理,不过由于没有格式规定,无法校验. 好在php有json-schema模块,可以用来验证json是否符合规定的格式. 安装使用composer composer require justinrainbow/json-schema:~1.3 新建一个schema文件,如:schema.json { "type&q

  • Python常用库大全及简要说明

    环境管理 管理 Python 版本和环境的工具 p:非常简单的交互式 python 版本管理工具.官网 pyenv:简单的 Python 版本管理工具.官网 Vex:可以在虚拟环境中执行命令.官网 virtualenv:创建独立 Python 环境的工具.官网 virtualenvwrapper:virtualenv 的一组扩展.官网 buildout:在隔离环境初始化后使用声明性配置管理.官网 包管理 管理包和依赖的工具. pip:Python 包和依赖关系管理工具.官网 pip-tools:

  • python库JsonSchema验证JSON数据结构使用详解

    目录 简单实例 type关键字 object关键字 属性 properties 必需属性 大小 数组属性 items List validation Tuple validation 长度 唯一性 通用关键字 元数据 枚举值 组合模式 anyOf oneOf allOf $schema关键字 正则表达式 构建复杂的模式 重用 JSON Schema是一个用于验证JSON数据结构的强大工具, 我查看并学习了JSON Schema的官方文档, 做了详细的记录, 分享一下. 我们可以使用JSON Sc

  • 基于Python的身份证验证识别和数据处理详解

    根据GB11643-1999公民身份证号码是特征组合码,由十七位数字本体码和一位数字校验码组成,排列顺序从左至右依次为: 六位数字地址码八位数字出生日期码三位数字顺序码一位数字校验码(数字10用罗马X表示) 校验系统: 校验码采用ISO7064:1983,MOD11-2校验码系统(图为校验规则样例) 用身份证号的前17位的每一位号码字符值分别乘上对应的加权因子值,得到的结果求和后对11进行取余,最后的结果放到表2检验码字符值..换算关系表中得出最后的一位身份证号码 代码: # coding=ut

  • 对python中dict和json的区别详解

    1.json 和 字典 区别 >>>import json >>>json.dumps({1:2}) >>>'{"1":2}' -------------------- >>>{1:2} >>>{1:@} 其中字典的格式是字典,json的格式是字符串,在传输的时候用的是字符串,所以如果要传输字典内容,就需要先进行字典转json. json中必须使用双引号,dict则可以用单引号也可以用双引号 2.

  • python库-dotenv包 及 .env配置文件详解

    目录 python库-dotenv包 | .env配置文件 背景 python-dotenv 如何使用 python库-dotenv包 | .env配置文件 背景 我们开发的每个系统都离不开配置信息,这些信息都非常敏感,一旦泄露出去后果非常严重,被泄露的原因一般是程序员将配置信息和代码混在一起导致的. 一般业务代码中,通过环境变量来加载敏感信息. 将敏感信息设置成环境变量,但是这样的信息非常多,挨个设置也太麻烦了.你一定希望可以将这些敏感信息单独放在一个文件中,始终与代码分开管理. 在pytho

  • Python黑魔法库安装及操作字典示例详解

    目录 1. 安装方法 2. 简单示例 3. 兼容字典的所有操作 4. 设置返回默认值 5. 工厂函数自动创建key 6. 序列化的支持 7. 说说局限性 本篇文章收录于<Python黑魔法手册>v3.0 第七章,手册完整版在线阅读地址:Python黑魔法手册 3.0 文档 字典是 Python 中基础的数据结构之一,字典的使用,可以说是非常的简单粗暴,但即便是这样一个与世无争的数据结构,仍然有很多人 "用不惯它" . 也许你并不觉得,但我相信,你看了这篇文章后,一定会和我一

  • python 读写中文json的实例详解

     python 读写中文json的实例详解 读写中文json 想要 读写中文json ,可以使用python中的 json 库可以对json进行操作.读入数据可以使用 json.load. f = file(path) data = json.load(f) json被载入到一个dict类型的object对象中. 使用 json.dump可以输出json.不过输出的文本并不是中文,而是转换为 utf-8的格式.此处需要: output = json.dump(jsonData,targetFil

  • Python Asyncio 库之同步原语常用函数详解

    目录 前记 0.基础 1.Lock 2.Event 4.Condition 5.Semaphore 前记 Asyncio的同步原语可以简化我们编写资源竞争的代码和规避资源竞争导致的Bug的出现. 但是由于协程的特性,在大部分业务代码中并不需要去考虑资源竞争的出现,导致Asyncio同步原语被使用的频率比较低,但是如果想基于Asyncio编写框架则需要学习同步原语的使用. 0.基础 同步原语都是适用于某些条件下对某个资源的争夺,在代码中大部分的资源都是属于一个代码块,而Python对于代码块的管理

  • python中requests库session对象的妙用详解

    在进行接口测试的时候,我们会调用多个接口发出多个请求,在这些请求中有时候需要保持一些共用的数据,例如cookies信息. 妙用1 requests库的session对象能够帮我们跨请求保持某些参数,也会在同一个session实例发出的所有请求之间保持cookies. 举个栗子,跨请求保持cookies,在命令行上输入下面命令: # 创建一个session对象 s = requests.Session() # 用session对象发出get请求,设置cookies s.get('http://ht

  • Python图像处理库PIL的ImageGrab模块介绍详解

    ImageGrab模块用于将当前屏幕的内容或者剪贴板上的内容拷贝到PIL图像内存. 当前版本只支持windows系统. 一.ImageGrab模块的函数 1.  Grab 定义:ImageGrab.grab()⇒ image ImageGrab.grab(bbox) ⇒ image 含义:(New in 1.1.3)抓取当前屏幕的快照,返回一个模式为"RGB"的图像.参数边界框用于限制只拷贝当前屏幕的一部分区域. 例子: >>> from PIL importImag

  • Python图像处理库PIL的ImageDraw模块介绍详解

    ImageDraw模块提供了图像对象的简单2D绘制.用户可以使用这个模块创建新的图像,注释或润饰已存在图像,为web应用实时产生各种图形. PIL中一个更高级绘图库见The aggdraw Module 一.ImageDraw模块的概念 1.  Coordinates 绘图接口使用和PIL一样的坐标系统,即(0,0)为左上角. 2.  Colours 为了指定颜色,用户可以使用数字或者元组,对应用户使用函数Image.new或者Image.putpixel.对于模式为"1","

随机推荐