【问题标题】:JSON Schema Validation ConditionalJSON 模式验证条件
【发布时间】:2020-10-20 08:27:16
【问题描述】:

所以我有这个架构,我正在尝试验证它,但也包括条件。我发现了一些以前提出的问题并按照提供的答案进行操作,但是我无法正确验证我的架构。

我遵循了这篇文章的答案:Stack Overflow JSON Schema Validation 但它不起作用

这是我的架构。基本上它应该需要基于commodityType 的某些字段,但它不起作用,并且模式验证器会抛出各种错误。我不确定我做错了什么......

我还应该补充一点,我正在使用 npm jsonschema 来处理模式...

  {
  "$id": "/commodity",
  "type": "object",
  "title": "Commodity Schema",
  "description": "Element of the Commodities Array",
  "examples": [
    {
      "commodityType": "Vehicles",
      "deliveryStopNumber": 1,
      "description": "Describes Freight (not used for vehicle commodities",
      "isInoperable": true,
      "length": 30,
      "make": "MAZDA",
      "model": "CX-7",
      "quantity": 3,
      "tariff": 260.34,
      "vehicleType": "SUV",
      "vin": "JM3ER29L670150717",
      "weight": 3331,
      "year": "2007"
    }
  ],
  "properties": {
    "commodityType": {
      "$id": "#/properties/commodityType",
      "type": ["string"],
      "title": "Commodity Type",
      "description": "Enum: Vehicles, Crushed Cars, Pallets, Bulk",
      "examples": ["Vehicles"],
      "enum": ["Vehicles", "Crushed Cars", "Pallets", "Bulk"]
    },
    "deliveryStopNumber": {
      "$id": "#/properties/deliveryStopNumber",
      "type": ["integer"],
      "title": "Delivery Stop Number",
      "description": "At which stop will this commodity be dropped off (ONLY used for multi drop orders)",
      "examples": [1],
      "default": 1
    },
    "description": {
      "$id": "#/properties/description",
      "type": ["string", "null"],
      "title": "Describes the Commodity",
      "description": "Freight Description (set to null for Vehicle commodities)",
      "examples": ["Heavy Tables"],
      "default": null
    },
    "isInoperable": {
      "$id": "#/properties/isInoperable",
      "type": ["boolean", "null"],
      "title": "Is Vehicle Inoperable",
      "description": "(Used for Vehicle commodities Only)",
      "examples": [true, false, null],
      "default": false,
      "enum": [true, false, null]
    },
    "length": {
      "$id": "#/properties/length",
      "type": ["integer", "null"],
      "title": "Length of Freight in Feet",
      "description": "(set to null for Vehicle commodities)",
      "examples": [30],
      "default": null
    },
    "make": {
      "$id": "#/properties/make",
      "type": ["string", "null"],
      "title": "Vehicle Make",
      "description": "",
      "examples": ["MAZDA"]
    },
    "model": {
      "$id": "#/properties/model",
      "type": ["string", "null"],
      "title": "Vehicle Model",
      "description": "",
      "examples": ["CX-7"]
    },
    "pickupStopNumber": {
      "$id": "#/properties/pickupStopNumber",
      "type": ["integer", "null"],
      "title": "Pickup Stop Number",
      "description": "At which stop will this commodity be picked up (only used for multi drop orders)",
      "examples": [1],
      "default": 0
    },
    "quantity": {
      "$id": "#/properties/quantity",
      "type": ["integer", "null"],
      "title": "Quantity of this item",
      "description": "i.e. Amount of Pallets (used for non-Vehicle commodities)",
      "examples": [5],
      "default": 0
    },
    "tariff": {
      "$id": "#/properties/tariff",
      "type": "number",
      "title": "Tariff",
      "description": "Amount Being Payed To RCG For This Commodity",
      "default": 0,
      "examples": [260.23]
    },
    "vehicleType": {
      "$id": "#/properties/vehicleType",
      "type": ["string"],
      "title": "Vehicle Type",
      "description": "Describes Vehicle (use Picklist)",
      "examples": ["JM3ER29L670150717"],
      "enum": [
        "Sedan",
        "Coupe",
        "Convertible",
        "SUV",
        "Minivan",
        "Pickup Truck (2 Door)",
        "Pickup Truck (4 Door)",
        "Motorcycle",
        "ATV",
        "Boat",
        "RV",
        "Trailer (5th Wheel)",
        "Trailer (Bumper Pull)",
        "Trailer (Gooseneck)",
        "Cargo Van",
        "Box Truck",
        "Pickup Dually",
        "Other"
      ]
    },
    "vin": {
      "$id": "#/properties/vin",
      "type": ["string", "null"],
      "title": "VIN",
      "description": "Vehicle Identification Number",
      "examples": ["JM3ER29L670150717"]
    },
    "weight": {
      "$id": "#/properties/weight",
      "type": ["number", "null"],
      "title": "Weight In Pounds",
      "description": "Weight of commodity (used for non-Vehicle commodities)",
      "examples": [3000],
      "default": null
    },
    "year": {
      "$id": "#/properties/year",
      "type": ["string", "null"],
      "title": "The year schema",
      "description": "Vehicle Year",
      "examples": ["2007"],
      "default": null
    }
  },
  "additionalProperties": false,
  "required": [
    "commodityType",
    "deliveryStopNumber",
    "pickupStopNumber",
    "tariff"
  ],
  "anyOf": [
    {
      "if": { "properties": { "commodityType": { "const": "Vehicles" } } },
      "then": {
        "required": [
          "commodityType",
          "deliveryStopNumber",
          "isInoperable",
          "make",
          "model",
          "pickupStopNumber",
          "tariff",
          "vehicleType",
          "vin",
          "year"
        ]
      },
      "else": false
    },
    {
      "if": { "properties": { "commodityType": { "const": "Pallets" } } },
      "then": {
        "required": [
          "commodityType",
          "deliveryStopNumber",
          "description",
          "length",
          "pickupStopNumber",
          "quantity",
          "tariff",
          "weight"
        ]
      },
      "else": false
    },
    {
      "if": { "properties": { "commodityType": { "const": "Crushed Cars" } } },
      "then": {
        "required": [
          "commodityType",
          "deliveryStopNumber",
          "description",
          "length",
          "pickupStopNumber",
          "quantity",
          "tariff",
          "weight"
        ]
      },
      "else": false
    },
    {
      "if": { "properties": { "commodityType": { "const": "Bulk" } } },
      "then": {
        "required": [
          "commodityType",
          "deliveryStopNumber",
          "description",
          "length",
          "pickupStopNumber",
          "quantity",
          "tariff",
          "weight"
        ]
      },
      "else": false
    }
  ]
}

【问题讨论】:

  • @Relequestual 我在帖子中按照您的示例进行操作,但似乎充满了错误。
  • 你能显示你得到的错误吗?这将是第一个线索。
  • 错误是条件中的所需数组中的任何字段都没有被检查。即我可以有品牌、型号和描述,它不会抛出任何错误。 @以太
  • “它不工作,模式验证器抛出各种错误”——什么错误?
  • @Ether 好吧,我尝试使用 if then else 并且那是它会告诉我需要属性 A 并且下一个错误是不允许使用属性 A(额外字段)。然后,当我切换到使用 anyOf 时,它停止验证 anyOf 范围内的所有内容。额外的字段或缺少的字段,这一切都会被忽略。被忽略的属性是我指的错误。

标签: json jsonschema json-schema-validator


【解决方案1】:

您可以将anyOf 更改为allOf,并删除所有else: false 子句,这至少会使错误(当它们发出时)更有帮助。

此外,if/then/else 直到草稿版本 7 才引入,因此如果您使用的评估器不支持该版本,这些关键字将被完全忽略。

【讨论】:

  • 是的,您对草稿版本的评论帮助我弄清楚我需要使用不同的 npm 包,然后我的所有问题都得到了解决。对于任何看到此评论的人,我选择了ajv
【解决方案2】:

在你有类似"type": ["integer", null], 的地方,它应该是"type": ["integer", "null"],type 接受一个字符串数组。它不起作用,因为null 不是字符串。

【讨论】:

  • 将 null 放入引号并不能修复条件。
  • 这是唯一的语法错误。如果其他方法不起作用,您需要更具体地说明您遇到的问题。
  • 对。 anyOf 数组中的条件不起作用。我的意思是我可以在同一个物体上拥有品牌和重量,并且不会出现任何错误。从模式中您可以看到,当商品类型为车辆时,应该发生 make ......但是整个条件似乎被忽略了......
  • 我打算编辑我​​的答案,但@Ether 的答案是正确的,所以我不会费心重复她的答案。
猜你喜欢
  • 2020-07-28
  • 2020-12-12
  • 2020-05-08
  • 2011-06-08
  • 2019-10-18
  • 2021-07-29
  • 1970-01-01
  • 2020-11-06
相关资源
最近更新 更多