【Python】schema 和 jsonschema

schema (XSD)

  XML Schema 描述 XML 文档的结构。可以指定一个.xsd (xml schema) 验证某个xml

  作用:定义 XML 文档的合法构建模块,类似 DTD(文档类型定义)

  参考地址: https://www.w3school.com.cn/schema/index.asp

  xml 了解:  https://www.cnblogs.com/phoenixy/p/15839462.html

 

 声明

<!-- xs:schema 根元素 包含属性声明-->
<!-- xmlns:xs 规定元素和数据类型取自命名空间 http://xxx 且使用前缀 xs: -->
<!-- targetNamespace 元素取自命名空间 http://xxx -->
<!-- elementFormDefault 元素必须被命名空间限定 -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.w3school.com.cn"  
xmlns="http://www.w3school.com.cn" 
elementFormDefault="qualified" 
>
    <!--简易元素-->
    <xs:element name="name"  type="xs:string"/>
</xs:schema>

 

 

 

 

 

数据类型

【Python】schema 和 jsonschema

拓展

【Python】schema 和 jsonschema

 

 

 

属性

<!-- xs:schema 根元素 包含属性声明-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
    <!-- attribution 属性定义 use规定属性是必须的 -->
    <xs:attribution name = "attr" type="xs:string" use="required"/>
    <!-- 带有属性 attr 的元素 -->
    <name attr="EN">lucy</name>
</xs:schema>

 

 

 

 

简易元素

  只有元素本身,不包含其他元素

<!-- 语法  xxx 指元素的名称,yyy 指元素的数据类型 -->
<!-- default 缺省值--> <xs:element name="xxx" type="yyy" default="name"/> <!--fixed 固定值--> <xs:element name="color" type="xs:string" fixed="name"/>

 

限定

【Python】schema 和 jsonschema

 

 

 

 

取值范围限定

  <!-- 带有限定的元素 age -->
    <xs:element name="age">
    
        <!-- 简易类型  -->
        <xs:simpleType>
        
            <!-- 元素限定 取值范围 在18-60之间 -->    
            <xs:restriction base="xs:integer">
            
                <!-- minInclusive 最小范围(包含); minExclusive 最小范围(不包含) -->
                <xs:minInclusive value="18"/>
                <!-- maxInclusive 最大范围(包含);  maxExclusive 最大范围(不包含) -->
                <xs:maxInclusive value="60"/>
                
            <!-- 限定结束  -->
            </xs:restriction>
            
        <!-- 简易类型结束 -->
        </xs:simpleType>
    
    <!-- 元素结束 -->
    <xs:element/>

 

 

枚举限定

    <xs:element name="idName">
        <!-- 简易类型  -->
        <xs:simpleType>
            <!-- 元素限定 枚举 -->    
            <xs:restriction base="xs:string">
            
                <!-- enumeration 枚举约束 在zhangsan、lisi、wangwu中 -->
                <xs:enumeration value="zhangsan"/>
                <xs:enumeration value="lisi"/>
                <xs:enumeration value="wangwu"/>
                
            </xs:restriction>
        </xs:simpleType>
    </xs:element>

 

 

 

模式限定

    <xs:element name="enName">
               <!-- 简易类型  -->
        <xs:simpleType>
            
             <!-- 元素限定 正则 -->    
            <xs:restriction base="xs:string">
            
                <!-- pattern 模式约束 三个a-z的数据且首字母大写 -->
                <xs:pattern value="[A-Z][a-z][a-z]"/>
                <!-- pattern 模式约束 5个阿拉伯数字 -->
                <xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/>
                <!-- pattern 模式约束 xyz中的一个 -->
                <xs:pattern value="[xyz]"/>
                <!-- pattern 模式约束 a-z中的0个或多个 -->
                <xs:pattern value="([a-z])*"/>
                <!-- pattern 模式约束 一对数据且一个小写一个大写 -->
                <xs:pattern value="([a-z][A-Z])+"/>
                <!-- pattern 模式约束 men或者women -->
                <xs:pattern value="men|women"/>
                <!-- pattern 模式约束 8个在 a-zA-Z0-9 范围内的数据 -->
                <xs:pattern value="[a-zA-Z0-9]{8}"/>
                
            </xs:restriction>
            
        </xs:simpleType>
    </xs:element>

 

 

 

空白字符限定

    <xs:element name="addr">
        <!-- 简易类型  -->
        <xs:simpleType>
            
             <!-- 元素限定 空白字符 -->    
            <xs:restriction base="xs:string">
            
                <!-- whiteSpace 不移除空白字符 -->
                <xs:whiteSpace value="preserve"/>
                
                <!-- whiteSpace 移除空白字符(包括换行、回车、空格以及制表符) -->
                <xs:whiteSpace value="replace"/>
                
                <!-- whiteSpace 去除开头结尾的空格,且换行、回车、空格以及制表符及连续空格会替换为单个空格 -->
                <xs:whiteSpace value="collapse"/>
                
            </xs:restriction>
            
        </xs:simpleType>
</xs:element>

 

 

 

 

长度限定

    <xs:element name="phone">
        <!-- 简易类型  -->
        <xs:simpleType>
            
             <!-- 元素限定 长度限定 -->    
            <xs:restriction base="xs:string">
            
                <!-- length 精确到11位字符 -->
                <xs::length value="11"/>
                
                <!-- minLength 最小7位字符,maxLength 最长11位字符 -->
                <xs:minLength value="7"/>
                <xs:maxLength value="11"/>
                            
            </xs:restriction>
            
        </xs:simpleType>

    </xs:element>

 

    <xs:element name="score">

        <!-- 简易类型  -->
        <xs:simpleType>
        
            <!-- 元素限定 精确位数限定 -->    
            <xs:restriction base="xs:string">
            
                <!-- totalDigits 允许总位数 -->
                <xs::length value="8"/>
                
                <!-- fractionDigits 小数位数 -->
                <xs:fractionDigits value="2"/>
                
                
            </xs:restriction>
            
        </xs:simpleType>

    </xs:element>

 

 

复合元素

<!-- xs:schema 根元素 包含属性声明-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
        
    <xs:element name="Name">
    
        <!-- 复合元素  -->
        <xs:complexType>
            <xs:sequence>
                <xs:element name="idName" type="xs:string"/>
                <xs:element name="custName" type="xs:string"/>
            </xs:sequence> 
        </xs:complexType>
        
    </xs:element>
    
<!-- 根元素结束 -->
</xs:schema>

 

 

 

 

 

 

数据类型限定

【Python】schema 和 jsonschema

 

 

 

  Order指示器

        <!-- 复合元素  -->
        <xs:complexType>
        
            <!-- 任意顺序出现 -->
            <xs:all>
                <xs:element name="idName" type="xs:string"/>
                <xs:element name="custName" type="xs:string"/>
            </xs:all>
    </xs:complexType>

 

       <!-- 选择出现 -->
            <xs:Choice >
                <xs:element name="idName" type="xs:string"/>
                <xs:element name="custName" type="xs:string"/>
            </xs:Choice >
       <!-- 按顺序出现 -->
            <xs:sequence>
                <xs:element name="idName" type="xs:string"/>
                <xs:element name="custName" type="xs:string"/>
            </xs:sequence>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

【Python】schema 和 jsonschema
<!--XMLSchema 根元素 包含属性声明;地址是schema用到的元素和数据类型来自命名空间 使用前缀xs:-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <!--复合元素-->
    <xs:element name="response">
        <xs:complexType>
          <xs:all maxOccurs="1">
            <xs:element name="content" type="xs:string"/>
            
            <xs:element name="respCode" minOccurs="0">
                <xs:simpleType>
                  <xs:restriction base="xs:string">
                    <!--处理成功-->
                    <xs:enumeration value="0000"/>
                    <!--业务处理异常-->
                    <xs:enumeration value="9999"/>
                  </xs:restriction>
                </xs:simpleType>
            </xs:element>

            <xs:element name="respMsg" type="xs:string"/>
          </xs:all>
        </xs:complexType>
    </xs:element>
</xs:schema>
XSD

 

 

 

 

 

 

 

jsonschema

  Json Schema 描述 Josn 文档的结构。

  官方版本参考: https://json-schema.org/specification-links.html

  jsonschema参考地址:https://www.freesion.com/article/7617866008/

 

jsonschema 组成结构

声明版本

# $schema 声明了针对该架构编写的JSON Schema标准版本
"$schema": "http://json-schema.org/draft-04/schema#",

 

 

文档标题

# title 文档标题,关键字是描述性的,用来对文档作补充说明
"title": "respMsg schema",

 

文档描述

# description 文档描述,关键字是描述性的,用来对文档作补充说明
"description": "validate result information",

 

字段描述

# default 描述字段 非必须字段
# "default":{}
"default": "描述字段"
"example": "描述字段(in draft 6),用于展示转换前的json; "
$comment: "描述字段(in draft 7 用于 schema 开发人员对文档进行注释,不需要展示给最终用户看。)"

 

 

【Python】schema 和 jsonschema
{
    // 声明
    "$schema": "http://json-schema.org/draft-04/schema#",
    // 标题
    "title":"Message",
    // 描述
    "description":"validata information",

}
示例

 

 

type类型

   【Python】schema 和 jsonschema

 

 

 

 

  Object 对象

{
    // 声明
    "$schema": "http://json-schema.org/draft-04/schema#",
    // 标题
    "title":"Message",
    // 描述
    "description":"validata information",

    // 类型 对象object
    "type":"object",

    //additionalProperties 默认true(允许properties之外的属性存在); false(不可以出现properties之外的属性)
    "additionalProperties":false,

    // required 存放必要属性列表
    "required":["respCode", "respMsg"]

    // object 出现的属性字段
    "properties":{
// string 字符串 "respCode":{"type": "string"} "respMsg":{"type": "string"} "failMsg":{"type": "string"} } // 属性数量最小值 "minProperties":2 // 属性数量最大值 "maxProperties":2 // dependencies 定义属性依赖值 "dependencies":{ // failMsg依赖于respMsg,当resoMsg存在时,failMsg才必须存在 "failMsg":["respMsg"] } }

 

 

  array 数组

{

    // 类型 数组 array
    "type":"array",
    
    // additionalItems默认true(允许items之外的项目存在); false(不可以出现items之外的项目)
    "additionalItems":false,
    
    // 针对数组中的所有元素类型进行验证,当数组中存在类型非string时。整个数组无效 (慎用)
    // "contains": {"type":"string"},

    // 验证数组中的所有元素的类型;每个元素都可以具有不同的类型,列表验证(任意长度的序列)和元组验证(固定长度的序列)
    "items":{
         // string 字符串
        "respCode":{"type": "string"}
        "respMsg":{"type": "string"}
        "failMsg":{"type": "string"}
    }
    // 非负数最小长度
    "minItems":2
    
    // 非负数最大长度
    "maxItems":2
        
    // 数组内元素唯一性验证 True 不能有重复元素
    "uniqueItems": false

}

 

 

  String 字符串

{

    // 类型 字符串 string
    "type":"string",
    
    // 字符串最大长度(包含)
    "maxLength":3,
    
    // 字符串最小长度(包含)
    "minLength":1,
    
    // 正则匹配字符串 示例:(xxx)xxx-xxxx x代表0-9的数字
    "pattern":"^(([0-9]{3}))?[0-9]{3}-[0-9]{4}$"
    
    // 指定MIME类型的字符串的内容 示例:包含一个HTML文档
    // "contentMediaType":"text/html",
    
    // 指定的编码用于存储内容 示例:使用Base64编码的PNG图像
    "contentEncoding":"base64",
    "contentMediaType":"image/png"
}

 

  

  number 数值(任何数字类型,整型或浮点型都可)

{

    // 类型 数值 number
    "type":"number",
    
    // 倍数 1的倍数
    // "multipleOf":1,
    
    // 最小值(包含)
    "minimum":1,
    
    // boolean不包含最小值 或 数值 开区间最小值
    "exclusiveMinimum":true,
    
    //最大值(包含)
    "maximum":999.99,
        
    // boolean不包含最大值 或 数值 开区间最大值
    "exclusiveMaximum":true
}

   

  

  integer 整型 (同number)

{

    // 类型整型
    "type":"integer",
    
    // 倍数 1的倍数
    // "multipleOf":1,
    
    // 最小值(包含)
    "minimum":1,
    
    // 不包含最小值
    "exclusiveMinimum":true,
    
    //最大值(包含)
    "maximum":999.99,
    
    
    // 不包含最大值
    "exclusiveMaximum":true
}

 

 

  boolean 布尔值

    仅包含true和false

 

  null 空值

    仅支持字段值为null

 

  any 任何值

    支持所有类型

 

  const 关键字验证

    验证值必须等于该常量,此关键字的值可以是任何类型,包括null。


  enum 枚举值  

    值只能是enum数组中的某一项 示例:["a", "b"]

  

   多类型

    【Python】schema 和 jsonschema

 

 

 

   判断 "if":{},"then":{},"else":{}

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "title":"Message",
    "description":"validata information",

    "type":"object",
    "properties":{
        "name":{
            "type":"string",
        },
        "sex":{
            "enum":["man", "woman"]
        }
    },
    // 条件
    "if":{
        "properties":{"age":{"const":"man"}}
    },
    // 符合条件 stage值
    "then":{
        "properties":{"stage":{"enum":["男"]}}
    },
    // 不符合条件 stage值
    "else":{
        "properties":{"stage":{"enum":["女"]}}
    }    
}

 

 

 

 

 

 

 

验证schema

jsonSchema 校验

def resp_json_check(self, data, cmd):

    json_schema_pathname = os.path.dirname(os.getcwd()) + "\\schema\\schema_%s.json" % cmd
    try:
        with open(json_schema_pathname, 'r', encoding='utf-8') as f:
            json_doc = commentjson.loads(f.read())
    except Exception as e:
        logs.warning("未进行数据规则校验,发生异常原因:" + str(e) + "[请前往目录检查文件]")
        return False
    else:
        try:
            # validate校验, 跟assert断言一个意思
            validate(instance=eval(data), schema=json_doc, format_checker=draft7_format_checker)

        except SchemaError as e:
            logs.error("SchemaError:数据不符合规则,请检查数据or修改校验文件")
            error1 = "验证模式schema出错:\n出错位置:{}\n提示信息:{}".format(" →".join([str(i) for i in e.path]), e.message)
            logs.error(error1)
            return error1

        except ValidationError as e:
            logs.error("ValidationError:数据不符合规则,请检查数据or修改校验文件")
            error2 = "验证模式schema出错:\n出错位置:{}\n提示信息:{}".format(" → ".join([str(i) for i in e.path]), e.message)
            logs.error(error2)
            return error2

        else:
            logs.info("基础校验 --> schema校验符合规则,验证通过!")
            return True

 

  

 xmlschema 校验

def resp_xsd_check(self, data):
    xml_doc = data
    xsd_schema_path = os.path.dirname(os.getcwd()) + "\\schema\\resp_xsd_check.xsd"
    
    try:
        with open(xsd_schema_path,encoding='utf-8') as f:
            xsd_doc = f.read()
    except Exception as e:
        logs.warning("未进行 xsd 数据规则校验,发生异常原因:" + str(e) + "[请前往目录检查文件]")
        return False
    else:
        xsd_doc_io = StringIO(xsd_doc)
        xsdCheck_doc = etree.parse(xsd_doc_io)

        xml_doc_io = StringIO(xml_doc)
        xmlschema = etree.XMLSchema(xsdCheck_doc)
        xmlCheck_doc = etree.parse(xml_doc_io)

        try:
            xmlschema.validate(xmlCheck_doc)
            xmlschema.assertValid(xmlCheck_doc)

        except lxml.etree.XMLSchemaParseError as xspe:
            logs.warning("XMLSchemaParseError occurred!" + str(xspe))
            return False

        except lxml.etree.XMLSyntaxError as xse:
            logs.warning("XMLSyntaxError occurred!" + str(xse))
            return False

        except lxml.etree.DocumentInvalid:
            logs.warning("xsd 数据不符合规则,请检查数据or完善文件")

            error = xmlschema.error_log.last_error
            if error:
                logs.error("异常原因:" + error.message)
                return False
            else:
                return True
        else:
            logs.info("xsd 数据符合规则,验证通过!")
            return True

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

拓展


 

1、UnicodeDecodeError:: 'utf-8' codec can't decode byte 0xc8 in position 0: invalid contin

  出现场景:读取json文件时报错

  问题原因:字符编码问题

    ASCII编码:大小写英文字母、数字和一些符号

    GB2312编码:收录汉字6763个,采用双字节编码。

    GBK编码:收录汉字21003个,采用双字节编码。

    GB18030编码:目前收录汉字70000余个,以及多种少数民族文字。采用单字节、双字节、四字节分段编码。

    Unicode编码:所有语言都统一到一套编码里,采用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。

    ASCII与Unicde转化:ASCII编码的数据用Unicode编码,只需要在前面补0就可以。

    bytes类型的数据用带b前缀的单引号或双引号表示

  解决方法:将json文件转换为需要读取的编码(utf-8模式(Notepad++ 设置 - 编码 - 使用utf-8编码)

 

2、

 

上一篇:itext poi 学习之旅 (3)读取数据库信息并由excel展现出来


下一篇:百度地图API报 APP服务被禁用