ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Python】schema 和 jsonschema

2022-01-25 16:31:47  阅读:263  来源: 互联网

标签:string Python doc json jsonschema xsd type schema


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>

 

 

 

 

 

数据类型

拓展

 

 

 

属性

<!-- 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"/>

 

限定

 

 

 

 

取值范围限定

  <!-- 带有限定的元素 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>

 

 

 

 

 

 

数据类型限定

 

 

 

  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>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<!--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 开发人员对文档进行注释,不需要展示给最终用户看。)"

 

 

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

}
示例

 

 

type类型

   

 

 

 

 

  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"]

  

   多类型

    

 

 

 

   判断 "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、

 

标签:string,Python,doc,json,jsonschema,xsd,type,schema
来源: https://www.cnblogs.com/phoenixy/p/15822342.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有