我正在尝试扩展JSON模式,它定义了一个枚举:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"objType": {
"enum": [ "A", "B" ]
},
"baseType": {
"type": "object",
"properties": {
"category": { "$ref": "#/definitions/objType" }
}
}
},
"properties": {
"A": {
"allOf": [
{ "$ref": "#/definitions/baseType" },
/* how to restrict inherited `category' to "A"? */
{ /* properties specific to A */ }
]
},
"B": {
"allOf": [
{ "$ref": "#/definitions/baseType" },
/* how to restrict inherited `category' to "B"? */
{ /* properties specific to B */ }
]
}
}
}
我不确定如何将继承的枚举属性限制为特定值。例如:
// passes validation
{
"category": "A",
"prop_A": "blah A"
}
// fails because `prop_A' is not valid property for category "B"
{
"category": "B",
"prop_A": "blah A"
}
感谢。
答案 0 :(得分:1)
JSON Schema是一个约束系统而不是面向对象的系统,因此作为概念的“继承”并不适合。有关详细信息,请参阅https://github.com/json-schema-org/json-schema-org.github.io/issues/148。
但是,在您的情况下,我认为约束系统正是您想要的。在约束系统中,您始终可以添加更多约束,但永远不能删除它们。因此,将枚举限制为其“继承”值的子集就像使用"allOf"
在原始的双值枚举顶部添加单值枚举的约束一样简单。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"definitions": {
"objType": {
"enum": [ "A", "B" ]
},
"baseType": {
"type": "object",
"properties": {
"category": { "$ref": "#/definitions/objType" }
}
}
},
"properties": {
"A": {
"allOf": [
{ "$ref": "#/definitions/baseType" },
{ "objType": { "enum": [ "A" ] }.
{ /* properties specific to A */ }
]
},
"B": {
"allOf": [
{ "$ref": "#/definitions/baseType" },
{ "objType": { "enum": [ "B" ] }.
{ /* properties specific to B */ }
]
}
}
}
您只需要在实际使用它的位置进一步约束每种类型属性的枚举。
答案 1 :(得分:0)
在Building a mount point schema示例中,他们的做法略有不同。每个 <?php
session_start();
$user_id = $_SESSION['sess_user_id'];
$role = $_SESSION['sess_userrole'];
$Address = $_SESSION['sess_address'];
$City = $_SESSION['sess_city'];
$avatar = $_SESSION['avatar'];
$currentuser = $_SESSION['sess_username'];
$first_name = $_SESSION['sess_first_name'];
$last_name = $_SESSION['sess_last_name'];
$id = $_SESSION['sess_hotel_id'];
$_SESSION['hotel_name'] = $name;
$_SESSION['hotel_image'] = $image;
if(isset($_POST["submitfeedback"]))
{
$link=mysqli_connect("127.0.0.1", "lakbayph", "aaEPl6122n");
mysqli_select_db($link,"lakbayph_category");
$title_of_feedback = $_POST['review_title'];
$textarea = $_POST['limitedtextarea'];
$count=0;
$res=mysqli_query($link,"select * from Reviews where review_title='$title_of_feedback'");
$count=mysqli_num_rows($res);
if($count>0)
{
echo "Sorry, this title is already used, try again";
}
else
{
print_r($_FILES);
$avatar_path = $link->real_escape_string('images/'.$_FILES['avatar']['name']);
if(preg_match("!image!", $_FILES['avatar']['type'])) {
if(copy($_FILES['avatar']['tmp_name'], $avatar_path)){
mysqli_query($link,"INSERT INTO `Reviews` VALUES('','$id','NONE','NONE','NONE','$user_id','$title_of_feedback','$textarea','$avatar_path')");
echo 'Registration succesful! Added $username to the database!';
header("location: SearcResult.php");
if ($link->query($sql) === true) {
$_SESSION['message'] = 'Registration succesful! Added $username to the database!';
header("location: welcome.php");
}
else {
echo "User could not be added to the database!";
}
}
else{
echo "File upload failed!";
}
}
else{
echo "Please only upload GIF and JPEG";
}
}
}
?>
指的是几种类型的对象之一:
storage
并且每个对象类型都包含具有不同值的"properties": {
"storage": {
"type": "object",
"oneOf": [
{ "$ref": "#/definitions/diskDevice" },
{ "$ref": "#/definitions/diskUUID" },
{ "$ref": "#/definitions/nfs" },
{ "$ref": "#/definitions/tmpfs" }
]
},
枚举。例如type
以这种方式指定diskDevice
type
而"properties": {
"type": { "enum": [ "disk" ] },
"device": {
"type": "string",
"pattern": "^/dev/[^/]+(/[^/]+)*$"
}
以这种方式指定nfs
type
也许您可以考虑按照这些方式重构您的架构。
答案 2 :(得分:0)
使用Schema Draft v6,这似乎是可能的:
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type": "object",
"oneOf": [
{
"additionalProperties": false,
"properties": {
"category": {
"type": "string",
"const": "A"
},
"prop_A": {
"type": "string"
}
}
},
{
"additionalProperties": false,
"properties": {
"category": {
"type": "string",
"const": "B"
},
"prop_B": {
"type": "string"
}
}
}
]
}