2017-07-24 50 views
1

使用Python和jsonschema我試圖驗證的ObjAObjB等來betatest.json如何指定JSON對象應該採用哪一個項目?

{ 
    "alpha": { 

     "beta": "ObjA" 
    } 
} 

分配在我的架構(testschema.jsonbetaoneOf多個項目,每個項目被定義爲下面(與ab不同的值,並且c

"ObjA": { 

    "type": "object", 
    "properties": { 

     "items": { 

      "a": [90, 95], 
      "b": [4, 8], 
      "c": [0.2, 0.6] 
     } 
    }, 

    "additionalProperties": false 
} 

也就是說,beta可以採用oneOf值爲ObjA,ObjB,ObjCObjD。我只是想說明它應該在test.json

"alpha": { 

    "type": "object", 
    "properties": { 

     "beta": { 

      "oneOf": [ 
       { 
        "type": "object", 
        "properties": { 

         "ObjA": { 

          "type": "object", 
          "properties": { 

           "items": { 

            "a": [90, 95], 
            "b": [4, 8], 
            "c": [0.2, 0.6] 
           } 
          }, 

          "additionalProperties": false 
         } 
        }, 

        "additionalProperties": false 
       }, 

       { 
        "type": "object", 
        "properties": { 

         "ObjB": { 

          "type": "object", 
          "properties": { 

           "items": { 

            "a": [100], 
            "b": [0], 
            "c": [0] 
           } 
          }, 

          "additionalProperties": false 
         } 
        } 
       }, 

       ... 
       ObjC and ObjD defined 
       ... 
      } 
     } 
    } 
}, 

但是使用哪一個,試圖驗證針對該架構在使用jsonschema.validate()

### Test the whole JSON is valid against the Schema 
def test_valid__JSON_against_schema(self): 

    with open(schema_filename) as schema_file: 
     test_schema = json.load('testschema.json') 
    schema_file.close() 

    with open(json_filename) as json_file: 
     test_json = json.load('test.json') 
    json_file.close() 

    validate(test_json, test_schema) 

我收到以下錯誤

Failed validating 'oneOf' in schema['properties']['alpha']['properties']['beta']: 

這裏是整個消息

E                  
====================================================================== 
ERROR: test_valid__JSON_against_schema (__main__.SchemaTests)   
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "test_test-variables.py", line 35, in test_valid__JSON_against_schema 
    validate(test_json, test_schema) 
    File "/local/tools/PACKAGES/python3/lib/python3.6/site-packages/jsonschema/validators.py", line 541, in validate 
    cls(schema, *args, **kwargs).validate(instance) 
    File "/local/tools/PACKAGES/python3/lib/python3.6/site-packages/jsonschema/validators.py", line 130, in validate 
    raise error 
jsonschema.exceptions.ValidationError: 'ObJA' is not valid under any of the given schemas 

Failed validating 'oneOf' in schema['properties']['alpha']['properties']['beta']: 
    {'oneOf': [{'additionalProperties': False, 
       'properties': {'ObjA': {'additionalProperties': False, 
              'properties': {'items': {'a': [0.2, 0.6], 
                    'b': [90, 95], 
                    'c': [4, 8]}}, 
              'type': 'object'}}, 
       'type': 'object'}, 
       {'additionalProperties': False, 
       'properties': {'ObjB': {'additionalProperties': False, 
              'properties': {'items': {'a': [0], 
                    'b': [100], 
                    'c': [0]}}, 
              'type': 'object'}}, 
       'type': 'object'}, 
       {'additionalProperties': False, 
       'properties': {'ObjC': {'additionalProperties': False, 
                'properties': {'items': {'a': [0], 
                      'b': [50], 
                      'c': [50]}}, 
                'type': 'object'}}, 
       'type': 'object'}, 
       {'additionalProperties': False, 
       'properties': {'ObjD': {'additionalProperties': False, 
               'properties': {'items': {'a': [100], 
                     'b': [0], 
                     'c': [0]}}, 
               'type': 'object'}}, 
       'type': 'object'}]} 

On instance['alpha']['beta']: 
    'ObjA' 

---------------------------------------------------------------------- 
Ran 1 test in 0.007s 

FAILED (errors=1) 

使用在線jsonschema驗證器(http://json-schema-validator.herokuapp.com/test.json未驗證,所以我從文件中刪除了任何提及的alpha(即,這個{ })和驗證報告以下

[ { 
    "level" : "warning", 
    "schema" : { 
    "loadingURI" : "#", 
    "pointer" : "/properties/alpha/properties/beta/oneOf/0/properties/ObjA/properties/items" 
    }, 
    "domain" : "syntax", 
    "message" : "the following keywords are unknown and will be ignored: [a, b, c]", 
    "ignored" : [ "a", "b", "c" ] 
} ] 

恢復test.json回,確認給

[ { 
    "level" : "warning", 
    "schema" : { 
    "loadingURI" : "#", 
    "pointer" : "/properties/alpha/properties/beta/oneOf/0/properties/ObjA/properties/items" 
    }, 
    "domain" : "syntax", 
    "message" : "the following keywords are unknown and will be ignored: [a, b, c]", 
    "ignored" : [ "a", "b", "c" ] 
}, { 
    "level" : "warning", 
    "schema" : { 
    "loadingURI" : "#", 
    "pointer" : "/properties/alpha/properties/beta/oneOf/0/properties/ObjA/properties/items" 
    }, 
    "domain" : "syntax", 
    "message" : "the following keywords are unknown and will be ignored: [a, b, c]", 
    "ignored" : [ "a", "b", "c" ] 
}, { 
    "level" : "warning", 
    "schema" : { 
    "loadingURI" : "#", 
    "pointer" : "/properties/alpha/properties/beta/oneOf/0/properties/ObjA/properties/items" 
    }, 
    "domain" : "syntax", 
    "message" : "the following keywords are unknown and will be ignored: [a, b, c]", 
    "ignored" : [ "a", "b", "c" ] 
}, { 
    "level" : "error", 
    "schema" : { 
    "loadingURI" : "#", 
    "pointer" : "/properties/alpha/properties/beta" 
    }, 
    "instance" : { 
    "pointer" : "/alpha/beta" 
    }, 
    "domain" : "validation", 
    "keyword" : "oneOf", 
    "message" : "instance failed to match exactly one schema (matched 0 out of 1)", 
    "matched" : 0, 
    "nrSchemas" : 1, 
    "reports" : { 
    "/properties/alpha/properties/beta/oneOf/0" : [ { 
     "level" : "warning", 
     "schema" : { 
     "loadingURI" : "#", 
     "pointer" : "/properties/alpha/properties/beta/oneOf/0/properties/ObjA/properties/items" 
     }, 
     "domain" : "syntax", 
     "message" : "the following keywords are unknown and will be ignored: [a, b, c]", 
     "ignored" : [ "a", "b", "c" ] 
    }, { 
     "level" : "error", 
     "schema" : { 
     "loadingURI" : "#", 
     "pointer" : "/properties/alpha/properties/beta/oneOf/0" 
     }, 
     "instance" : { 
     "pointer" : "/alpha/beta" 
     }, 
     "domain" : "validation", 
     "keyword" : "type", 
     "message" : "instance type (string) does not match any allowed primitive type (allowed: [\"object\"])", 
     "found" : "string", 
     "expected" : [ "object" ] 
    } ] 
    } 
} ] 

有誰知道這樣做的正確方法是什麼?

謝謝。

+0

幾乎不可能不知道你想驗證的JSON實例是什麼樣的。因爲你正在動態生成它可能是任何東西。 –

+0

文本開始 - 「測試版」:「ObjA」 - 我編輯了句子和JSON,使其更清晰。 – Dodomac

+0

是的,這正是問題所在。嘗試根據模式驗證「某些內容」時,您會收到驗證錯誤。你試圖驗證的「東西」是失敗的驗證。不幸的是,我們不可能看到*爲什麼*它失敗了(因此能夠提供一些幫助),因爲我們不知道它是什麼樣子。 –

回答

3

讓我們分離失敗模式的一部分。

{ 
    "type": "object", 
    "properties": { 
    "ObjA": { 
     "type": "object", 
     "properties": { 
     "items": { 
      "a": [90, 95], 
      "b": [4, 8], 
      "c": [0.2, 0.6] 
     } 
     }, 
     "additionalProperties": false 
    } 
    }, 
    "additionalProperties": false 
} 

這是valiating你這部分測試數據

"ObjA" 

你看到的是告訴你,測試數據是一個字符串的錯誤,但該模式要求它是一個對象。

您的模式相匹配

測試數據將是這個樣子

{ 
    "ObjA": { 
    "items": ??? 
    } 
} 

我用???這裏,是因爲這裏的值可以是有效的JSON任意值。原因是因爲此架構不包含任何JSON模式關鍵字。

{ 
    "a": [90, 95], 
    "b": [4, 8], 
    "c": [0.2, 0.6] 
} 

因此,它可以是什麼值沒有限制。您看到的警告消息告訴您,abc不是關鍵字。

我不知道你用這個模式表達什麼,但是它與測試數據中的簡單字符串相差甚遠。

編輯迴應評論

這聽起來像你要使用JSON模式的東西,它是不適合。該模式應該只描述用戶需要關注的內容。您將不得不在另一個步驟中將用戶值映射到硬編碼結構。無論如何,這聽起來像你需要的是enum而不是oneOf

{ 
    "enum": ["ObjA", "ObjB", "ObjC", "ObjD"] 
} 

{ 
    "enum": [ 
    { 
     "a": [90, 95], 
     "b": [4, 8], 
     "c": [0.2, 0.6] 
    }, 
    { 
     "a": [100], 
     "b": [0], 
     "c": [0] 
    }, 
    ... 
    ] 
} 

沒有辦法兼得。如果你真的需要在你的模式中表達,我會添加一個顯示映射的自定義關鍵字。一個驗證器會忽略它(你可能會得到一個警告),但是這種關係將會被人類讀者和可能的定製工具所表達。它可能是這個樣子

{ 
    "enum": ["ObjA", "ObjB", "ObjC", "ObjD"] 
    "enumValues": { 
    "ObjA": { 
     "a": [90, 95], 
     "b": [4, 8], 
     "c": [0.2, 0.6] 
    }, 
    "ObjB": { 
     "a": [100], 
     "b": [0], 
     "c": [0] 
    }, 
    ... 
    ] 
} 

enum講述值允許哪些用戶和驗證器可以檢查此。然後,enumValues關鍵字是我們爲了表示枚舉值與它們的實際值之間的關係而編寫的。

+0

值a,b和c是ObjA,ObjB,ObjC和ObjD的固定數組。我只想將整個ObjA分配給beta,而不指定它的固定內容,換句話說,我試圖通過僅分配對象來爲多個數組分配一個JSON對象。我會將這些信息添加到原始問題中。 – Dodomac

+0

+1用於識別問題。仍然需要一種方法來正確指定具有多個設定值數組(a,b和c)的對象。它本身就是一個對象(ObjA),這是一個可供選擇的選擇。 – Dodomac

+0

也許問題是我試圖在架構中指定值(您在這裏提到https://stackoverflow.com/a/30465935/1413785)。我這樣做的原因是因爲我不希望用戶指定這些值,因爲它們是他們想要執行的測試類型的設置值。 – Dodomac

相關問題