Json高階使用和一些開源庫的用法用途(基本上包含大部分需求)

參考資料:
http://json-schema.org/
https://github.com/Julian/jsonschema
https://python-jsonschema.readthedocs.io/en/stable/
https://github.com/dmeranda/demjson
https://jsonschema.net/#/editor
https://github.com/json-path/JsonPath

1. 總體介紹

本文嘗試通過json數據校驗方法解決如下幾個問題:

  • 1.數據沒有校驗,系統處於裸奔狀態,導致後期維護成本高;
  • 2.編寫一堆校驗代碼,混雜在業務代碼中,導致代碼可讀性降低;
  • 3.API交付的時候提供一大段接口描述文檔,但用戶還是要揣測文檔意思。
  • 4.自動校驗json格式
  • 5.自動糾正json錯誤格式
  • 6.對於多層嵌套問題進行深入探討
  • 7.對於array拆分展開
  • 8.特殊字符處理

2. Json Schema

Json Schema主要用在前後端Json數據交互校驗上,一般解決的需求是1,2,3的問題,規定好每一個字段是什麼類型比如:

from jsonschema import validate
schema = {
  "definitions": {},
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/example.json",
  "type": "object",
  "title": "The Root Schema",
  "required": [
    "checked",
    "dimensions",
    "id",
    "name",
    "price",
    "tags"
  ],
  "properties": {
    "checked": {
      "$id": "/properties/checked",
      "type": "boolean",
      "title": "The Checked Schema",
      "default": false,
      "examples": [
        false
      ]
    },
    "dimensions": {
      "$id": "/properties/dimensions",
      "type": "object",
      "title": "The Dimensions Schema",
      "required": [
        "width",
        "height"
      ],
      "properties": {
        "width": {
          "$id": "/properties/dimensions/properties/width",
          "type": "integer",
          "title": "The Width Schema",
          "default": 0,
          "examples": [
            5
          ]
        },
        "height": {
          "$id": "/properties/dimensions/properties/height",
          "type": "integer",
          "title": "The Height Schema",
          "default": 0,
          "examples": [
            10
          ]
        }
      }
    },
    "id": {
      "$id": "/properties/id",
      "type": "integer",
      "title": "The Id Schema",
      "default": 0,
      "examples": [
        1
      ]
    },
    "name": {
      "$id": "/properties/name",
      "type": "string",
      "title": "The Name Schema",
      "default": "",
      "examples": [
        "A green door"
      ],
      "pattern": "^(.*)$"
    },
    "price": {
      "$id": "/properties/price",
      "type": "number",
      "title": "The Price Schema",
      "default": 0.0,
      "examples": [
        12.5
      ]
    },
    "tags": {
      "$id": "/properties/tags",
      "type": "array",
      "title": "The Tags Schema",
      "items": {
        "$id": "/properties/tags/items",
        "type": "string",
        "title": "The 0 Schema",
        "default": "",
        "examples": [
          "home",
          "green"
        ],
        "pattern": "^(.*)$"
      }
    }
  }
}

test_json = {
  "checked": false,
  "dimensions": {
    "width": 5,
    "height": 10
  },
  "id": 1,
  "name": "A green door",
  "price": 12.5,
  "tags": [
    "home",
    "green"
  ]
}
test_val = validate(instance=test_json,schema=test_schema)

具體用法可參考json schema的官方網站,比如自己寫的json可以通過https://jsonschema.net/#/editor進行轉換成schema格式做自動校驗

3. JsonPath

JsonPath是一種簡單的方法來提取給定JSON文檔的部分內容。 JsonPath有許多編程語言,如Javascript,Python和PHP,Java。

JsonPath提供的json解析非常強大,它提供了類似正則表達式的語法,基本上可以滿足所有你想要獲得的json內容。下面我把官網介紹的每個表達式用代碼實現,可以更直觀的知道該怎麼用它。

JsonPath表達式總是以與XPath表達式結合使用XML文檔相同的方式引用JSON結構。

JsonPath中的“根成員對象”始終稱爲$,無論是對象還是數組。

JsonPath表達式可以使用點表示法

$.store.book [0].title

或括號表示法

$['store']['book'][0]['title']

3.1 操作符

操作	說明
$	查詢根元素。這將啓動所有路徑表達式。
@	當前節點由過濾謂詞處理。
*	通配符,必要時可用任何地方的名稱或數字。
..	深層掃描。 必要時在任何地方可以使用名稱。
.<name>	點,表示子節點
['<name>' (, '<name>')]	括號表示子項
[<number> (, <number>)]	數組索引或索引
[start:end]	數組切片操作
[?(<expression>)]	過濾表達式。 表達式必須求值爲一個布爾值。

3.2 函數

函數可以在路徑的尾部調用,函數的輸出是路徑表達式的輸出,該函數的輸出是由函數本身所決定的。

函數	描述	輸出
min()	提供數字數組的最小值	Double
max()	提供數字數組的最大值	Double
avg()	提供數字數組的平均值	Double
stddev()	提供數字數組的標準偏差值	Double
length()	提供數組的長度	Integer

3.3 過濾器運算符

過濾器是用於篩選數組的邏輯表達式。一個典型的過濾器將是[?(@.age > 18)],其中@表示正在處理的當前項目。 可以使用邏輯運算符&&和||創建更復雜的過濾器。 字符串文字必須用單引號或雙引號括起來([?(@.color == ‘blue’)] 或者 [?(@.color == “blue”)]).

操作符	描述
==	left等於right(注意1不等於'1')
!=	不等於
<	小於
<=	小於等於
>	大於
>=	大於等於
=~	匹配正則表達式[?(@.name =~ /foo.*?/i)]
in	左邊存在於右邊 [?(@.size in ['S', 'M'])]
nin	左邊不存在於右邊
size	(數組或字符串)長度
empty	(數組或字符串)爲空

3.4 python版本的jsonpath

https://github.com/kennknowles/python-jsonpath-rw
此庫主要是爲了方便json數據查詢

from jsonpath_rw import jsonpath, parse
sJOSN = {
        "test": "123",
        "remote_user": "-",
        "request_time": {
            "receive_time": "14",
            "from_time": "23",
            "to_time": 45
        },
        "day1": {
            "day2": {
                "day3-1": "123",
                "day3-2": "234"
            }
        },
    }

jsonpath_expr = parse('day1.day2.day3-2')
match = jsonpath_expr.find(sJOSN)
print("day:",match,type(match))

4、對json數據格式自動檢測自動糾正

當時業務上有這方面需求,找了好多關於json開源的庫,奈何沒找到想要,不過幸好找到相似的開源庫,在此demjson庫基礎上做了修改,已經放到GitHub上,有興趣的可自取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章