Условие проверки схемы JSON

Итак, у меня есть эта схема, и я пытаюсь ее проверить, но также включаю условные выражения. Я нашел несколько ранее заданных вопросов и следил за предоставленными ответами, однако мне не удалось правильно проверить свою схему.

Я последовал ответу из этого сообщения: Проверка схемы JSON при переполнении стека, но он не работает

Вот моя схема. По сути, он должен требовать определенные поля на основе 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
    }
  ]
}

person search-learn    schedule 20.10.2020    source источник
comment
@Relequestual Я последовал вашему примеру из сообщения, но, похоже, он полон ошибок.   -  person search-learn    schedule 20.10.2020
comment
Не могли бы вы показать ошибки, которые вы получаете? Это было бы первым ключом к разгадке.   -  person Ether    schedule 20.10.2020
comment
Ошибка в том, что ни одно из полей в требуемых массивах из условных операторов даже не проверяется. т.е. у меня может быть марка, модель и описание, никаких ошибок не возникает. @Ether   -  person search-learn    schedule 20.10.2020
comment
он не работает, а валидаторы схемы выдают всевозможные ошибки - какие ошибки?   -  person Ether    schedule 20.10.2020
comment
@Ether хорошо, я попытался использовать if then else, и тогда он сказал мне, что свойство A требуется, и следующей ошибкой будет свойство A не разрешено (дополнительное поле). Затем, когда я переключился на использование anyOf, он перестал проверять все в области anyOf. Дополнительные поля или отсутствующие поля, все это игнорируется. Свойства, игнорируемые - это ошибки, о которых я говорю.   -  person search-learn    schedule 20.10.2020


Ответы (2)


Вы можете изменить anyOf на allOf и отбросить все предложения else: false, что, по крайней мере, сделает ошибки (когда они будут выданы) более полезными.

Кроме того, if / then / else не были представлены до черновой версии 7, поэтому, если вы используете оценщик, который не поддерживает эту версию, эти ключевые слова будут полностью проигнорированы.

person Ether    schedule 20.10.2020
comment
Да, ваш комментарий относительно черновых версий помог мне понять, что мне нужно использовать другой пакет npm, и тогда все мои проблемы были исправлены. Для всех, кто просматривает этот комментарий. Я выбрал ajv. - person search-learn; 21.10.2020

В местах, где есть что-то вроде "type": ["integer", null],, должно быть "type": ["integer", "null"],. type принимает массив строк. Это не работает, потому что null не является строкой.

person Jason Desrosiers    schedule 20.10.2020
comment
Помещение нуля в кавычки не исправило условные выражения. - person search-learn; 20.10.2020
comment
Это была единственная синтаксическая ошибка. Если что-то еще не работает, вам нужно более подробно рассказать о проблеме, с которой вы столкнулись. - person Jason Desrosiers; 20.10.2020
comment
Верно. Условные выражения в массиве anyOf не работают. Под этим я подразумеваю, что у меня могут быть марка и вес одного и того же объекта, и я не получаю никаких ошибок. Из схемы видно, что make должна выполняться, когда productType - это средство передвижения ... однако все это условие, похоже, игнорируется .. - person search-learn; 20.10.2020
comment
Я собирался отредактировать свой ответ, но ответ @Eter правильный, поэтому я не буду повторять ее ответ. - person Jason Desrosiers; 20.10.2020