Nano Hash - криптовалюты, майнинг, программирование

Проверка схемы JSON объектов условного массива

У меня есть два типа наборов данных: csv или данные фиксированной длины. В данных csv список полей представляет собой просто список имен, в то время как в данных фиксированной длины каждое поле определяется fieldName и fieldLength. Мне нужна схема json для проверки обоих случаев, но, попробовав несколько решений, включая эти, я не уверен, что это можно сделать. Или, может быть, мое понимание схемы JSON все еще далеко от совершенства.

json:

{
      "dataset": "csv data",
      "dataFormat": "csv",
      "fieldList": [{
                  "fieldName": "id"
            },
            {
                  "fieldName": "num"
            },
            {
                  "fieldName": "struct"
            }
      ]
}

{
    "dataset": "fixed length",
    "dataFormat": "fixed",
    "fieldList": [{
            "fieldName": "id",
            "fieldLength": 13
        },
        {
            "fieldName": "num"
        },
        {
            "fieldName": "struct"
        }
    ]
}

JSON-схема:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "dataset",
    "dataFormat",
    "fieldList"
  ],
  "properties": {
    "dataset": {
      "$id": "#/properties/dataset",
      "type": "string"
    },
    "dataFormat": {
      "$id": "#/properties/dataFormat",
      "type": "string",
      "enum": [
        "csv",
        "fixed"
      ]
    },
    "fieldList": {
      "$id": "#/properties/fieldList",
      "type": "array",
      "additionalItems": true,
      "items": {
        "$id": "#/properties/fieldList/items",
        "type": "object",
        "additionalProperties": true,
        "required": [
          "fieldName"
        ],
        "if": {
          "properties": {
            "dataFormat": {
              "const": "fixed"
            }
          }
        },
        "then": {"items":{
          "required": [
            "fieldLength"
          ]}
        },
        "properties": {
          "fieldName": {
            "$id": "#/properties/fieldList/items/properties/fieldName",
            "type": "string"
          },
          "fieldLength": {
            "$id": "#/properties/fieldList/items/properties/fieldLength",
            "type": "integer"
          }
        }
      }
    }
  }
}

Оба документа проходят положительную проверку, даже если в «фиксированном» типе только первый элемент включает требуемую длину поля. Любое предложение ?

15.04.2020

Ответы:


1

В вашей схеме есть несколько вещей, которые можно улучшить:

  1. if/then не в том месте. Прямо сейчас if ищет свойство "dataFormat" внутри "fieldList" items и никогда не находит его. Аналогичным образом then пытается обеспечить наличие свойства "fieldLength" в "fieldList".items.items (а поскольку "fieldList".items является object, а не array, это будет просто проигнорировано.
  2. Вы должны удалить атрибут additionalItems. Чтобы процитировать json-schema.org:
    # P2#
  3. Вы можете удалить атрибут additionalProperties, поскольку его значение по умолчанию уже равно true. Еще одна цитата из json-schema.org: < цитата> #P3#
  4. Атрибуты $id не имеют большого значения (и несовместимы с новым проектом 2019-09, где они разрешены только в новом ключевом слове $anchor). Вы можете опустить их.

Ваша основная проблема - это пункт № 1 здесь. Вы должны быть в состоянии достичь того, чего хотите, добавив что-то вроде этого на верхнем уровне:

"oneOf": [
  {
    "properties": {
      "dataFormat": { "const": "csv" }
    }
  },
  {
    "properties": {
      "dataFormat": { "const": "fixed" },
      "fieldList": {
        "items": {
          "required": ["fieldLength"]
        }
      }
    }
  }
]

Полная схема может выглядеть так:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "dataset",
    "dataFormat",
    "fieldList"
  ],
  "properties": {
    "dataset": {
      "$id": "#/properties/dataset",
      "type": "string"
    },
    "dataFormat": {
      "$id": "#/properties/dataFormat",
      "type": "string",
      "enum": [
        "csv",
        "fixed"
      ]
    },
    "fieldList": {
      "$id": "#/properties/fieldList",
      "type": "array",
      "items": {
        "$id": "#/properties/fieldList/items",
        "type": "object",
        "required": [
          "fieldName"
        ],
        "properties": {
          "fieldName": {
            "$id": "#/properties/fieldList/items/properties/fieldName",
            "type": "string"
          },
          "fieldLength": {
            "$id": "#/properties/fieldList/items/properties/fieldLength",
            "type": "integer"
          }
        }
      }
    }
  },
  "oneOf": [
    {
      "properties": {
        "dataFormat": {
          "const": "csv"
        }
      }
    },
    {
      "properties": {
        "dataFormat": {
          "const": "fixed"
        },
        "fieldList": {
          "items": {
            "required": [
              "fieldLength"
            ]
          }
        }
      }
    }
  ]
}

Для полноты: вы можете добиться того же и с if/then:

"if": {
  "properties": {
    "dataFormat": {
      "const": "fixed"
    }
  }
},
"then": {
  "properties": {
    "fieldList": {
      "items": {
        "required": [
          "fieldLength"
        ]
      }
    }
  }
}
16.04.2020
  • Спасибо, ваши решения работают отлично! К сожалению, мой вариант использования немного сложнее, чем тот, что представлен в моем вопросе: набор данных представляет собой массив, каждый элемент которого имеет свой собственный список полей. Я попытался адаптировать ваше решение oneOf, добавив набор данных/элементы перед списком полей, но безуспешно... 16.04.2020
  • @mre, возможно, добавьте это с помощью редактирования в нижней части вашего вопроса, и я также могу попытаться помочь вам с этим. 16.04.2020
  • @mre тебе придется добавить dataset/items/properties перед fieldList, я думаю. Не забывайте, что последнее properties. 16.04.2020
  • Еще раз спасибо @Carsten, последний properties сделал свое дело, теперь все работает !!! 17.04.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..