2017-02-10 81 views
1

這部分是針對數據驗證,但如果可以使用json模式驗證來完成,那麼該模式可以更好地滿足我的需求。我輸入的是:二叉樹邏輯運算的Json模式驗證

(1 or (1 and 0)) => true 

成爲一個JSON對象:

[1, [1, 0]] 

所以驗證應該給沒有錯誤,但目前我的架構不能嵌套數據之間的手柄或情況正常。

{ 
    "allOf": [ 
    {"$ref": "#/definitions/_items"}, 
    { 
     "allOf": [ 
     {"$ref": "#/definitions/_or"}, 
     { 
      "items": { 
      "$ref": "#/definitions/_and" 
      } 
     } 
     ] 
    } 
    ], 
    "definitions": { 
    "_items": { 
     "minItems": 1, 
     "maxItems": 2, 
     "type": "array", 
     "items": { 
     "anyOf": [ 
      {"enum": [1,0]}, 
      {"$ref": "#/definitions/_items"} 
     ] 
     } 
    }, 
    "_or": { 
     "not": { 
     "type": "array", 
     "items": { 
      "not": { 
      "anyOf": [ 
       {"enum": [1]}, 
       {"$ref": "#/definitions/_items"} 
      ] 
      } 
     } 
     } 
    }, 
    "_and": { 
     "items": { 
     "anyOf": [ 
      {"enum": [1]}, 
      {"$ref": "#/definitions/_items"} 
     ] 
     } 
    } 
    } 
} 

驗證下一個數據對模式:

[1,0] is valid, ok 
[1,1] is valid, ok 
[0,1] is valid, ok 
[0,0] not valid, ok 
[[1,1],1] valid, ok 
[[1,1],0] valid, ok 

但:

[[1,0],1] not valid, not ok! 
[[0,0],1] not valid, not ok! 

因爲無論開啓或操作有1,如果只是滿足_items定義,以便左側不應該的問題。

所以我的問題是我應該如何改變模式,以便任何OR運算符都足夠有效的輸入?

更多的例子請通過@esp:通過邏輯表達式和相應的JSON數據

我輸入例子:

1 or (1 and 0)) => [1, [1, 0]] => true 
1 or (0 and 1)) => [1, [0, 1]] => true 
1 or (1 and 1)) => [1, [0, 0]] => true 
1 or (0 and 0)) => [1, [0, 0]] => true 
1 or (1)) => [1, [1]] => true 
1 or (0)) => [1, [0]] => true 
1 or 1 => [1, 1 => true 
1 or 0 => [1, 0] => true 
0 or 1 => [0, 1] => true 
0 or 0 => [0, 0] => false 

我也給左側的幾個例子嵌套,但不是全部,因爲組合很快就會變得很混亂:

(1 and 0) or (1 and 0)) => [[1, 0], [1, 0]] => false 
(0 and 0) or (0 and o)) => [[0, 0], [0, 0]] => false 
(1 and 1) or (1 and 0)) => [[1, 1], [1, 0]] => true 
(1 and 0) or (1 and 1)) => [[1, 0], [1, 1]] => true 
(1 and 1) or (1 and 1)) => [[1, 1], [1, 1]] => true 
+0

您能定義所有可能的輸入和預期輸出嗎?有些示例不匹配x或(y和z)模式。 – esp

+0

另外似乎有兩個問題 - 表達式是否匹配模式以及它是否爲真,因此您可能需要兩個模式而不是一個,否則如何區分不匹配模式和false? – esp

+0

@esp:新增示例。因此,輸入可以是:[p]或[q]或[p,q]或[p,[q]]或[[p],q]或[[p],[q]]'二進制項目的邊可以是數字1,0或包含至少一個相似項目的集合,但最多兩個。這應該已經用_items定義完成。 – MarkokraM

回答

0

由於排列組合很少,枚舉可能的狀態使得模式更簡單,更容易閱讀。

{ 
    "type": "array", 
    "minItems": 1, 
    "maxItems": 2, 
    "items": { 
    "anyOf": [ 
     { "enum": [0, 1] }, 
     { "enum": [[0], [1]] }, 
     { "enum": [[0, 0], [0, 1], [1, 0], [1, 1]] } 
    ] 
    }, 
    "allOf": [{ "$ref": "#/definitions/_or" }] 
    "definitions": { 
    "_or": { 
     "not": { 
     "items": { 
      "not": { "$ref": "#/definitions/_and" } 
     } 
     } 
    }, 
    "_and": { "enum": [1, [1], [1, 1]] } 
    } 
} 
+0

對。二叉樹Im掙扎着,有無限的嵌套分支,這是問題的一部分。我認爲它需要遞歸驗證。但更嚴格地說我的問題,你的答案似乎工作。 – MarkokraM

+0

@MarkokraM它仍然不清楚,如果它是遞歸樹,有沒有ORs的水平,但最後,只有最後有AND或有在所有級別,但第一個AND。 – esp

+0

正確。不同二進制節點的操作符應該從根開始嵌套allOf部分來定義,因爲在我的示例中,現在有兩個級別,但可以是任何。 – MarkokraM

1

使用草案-06的關鍵字「包含」(用於驗證陣列包含至少一個項目相匹配的模式)和「常量」(等同於「枚舉」與一個允許的值):

{ 
    "contains": { "$ref": "#/definitions/one" }, 
    "definitions": { 
    "one": { 
     "anyOf": [ 
     { "const": 1 }, 
     { "$ref": "#/definitions/all" } 
     ] 
    }, 
    "all": { 
     "type": "array", 
     "items": { "$ref": "#/definitions/one" } 
    } 
    } 
} 

正如我在評論中寫的,這個模式只評估你的布爾邏輯,它不驗證樹是否正確。除此之外,它還評估所有級別的AND。

沒有草稿-06的關鍵字,您可以:

{ 
    "not": { "items": { "not": { "$ref": "#/definitions/one" } } }, 
    "definitions": { 
    "one": { 
     "anyOf": [ 
     { "enum": [1] }, 
     { "$ref": "#/definitions/all" } 
     ] 
    }, 
    "all": { 
     "type": "array", 
     "items": { "$ref": "#/definitions/one" } 
    } 
    } 
} 

要驗證樹結構是有效的,你需要另外一個簡單的模式:

{ 
    "type": "array", 
    "minItems": 1, 
    "maxItems": 2, 
    "items": { 
    "anyOf": [ 
     { "enum": [0, 1] }, 
     { "$ref": "#" } 
    ] 
    } 
} 

您可以在一個與連接這兩個模式「 allOf「,但是你不會看到具有無效結構的樹和評估爲假的樹之間的區別。

+0

所以這意味着它不可能通過嵌套結構和枚舉部分在同一時間進行接縫驗證的方式進行驗證工作? – MarkokraM

+0

對不起,我不明白。你可以合併兩個模式,如果這就是你的意思 – esp

+0

我試圖稍後改進。我懷疑我的原始問題並不太清楚。 – MarkokraM