node.js - 如何声明嵌套属性的依赖关系?

标签 node.js jsonschema ajv

我正在使用 JSON 架构的 Draft-04。是否可以根据子属性的存在和/或依赖于子属性来设置依赖关系?或者我是否被迫使用 allOf 来管理这些类型的依赖项?

我有以下内容(您可以在 https://repl.it/@neverendingqs/JsonSchemaNestedDependencies 上玩它):

'use strict';

const Ajv = require('ajv');
const assert = require('chai').assert;

// Using ajv@5.5.1
const draft4 = require('ajv/lib/refs/json-schema-draft-04.json');

const schema = {
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "foo1": {
      "type": [ "object" ],
      "properties": {
        "bar1": { "type": "string" }
      }
    },
    "foo2": {
      "type": [ "object" ],
      "properties": {
        "bar2": { "type": "string" }
      }
    }
  },
  "dependencies": {
    "foo1": ["foo2"],
    
    // Is this possible?
    "foo1/bar1": ["foo2/bar2"]
  }
};

const schemaName = 'my-schema';

const ajv = new Ajv();
ajv.addMetaSchema(draft4);
ajv.addSchema(schema, schemaName);


assert.isTrue(
  ajv.validate(schemaName, {
    "foo1": { "bar1": "a" },
    "foo2": { "bar2": "c" }
  }),
  ajv.errorsText(ajv.errors, { dataVar: 'event' })
);

assert.isFalse(ajv.validate(schemaName, {
  "foo1": { "bar1": "a" }
}));

// Looking to cause this to pass
assert.isFalse(ajv.validate(schemaName, {
  "foo1": { "bar1": "a" },
  "foo2": {}
}));

我正在寻找 Draft-04 答案,但也对使用后续规范的答案感兴趣。

编辑:Draft-04http://json-schema.org/specification-links.html#draft-4 下的规范。具体来说,我使用的是在验证规范下定义的依赖项 ( https://datatracker.ietf.org/doc/html/draft-fge-json-schema-validation-00 )

最佳答案

如果依赖项支持JSON指针那就太好了,但事实并非如此。你必须使用蕴涵来解决这个问题。我使用定义对其进行了分解,以帮助更清楚地了解正在发生的情况。

首先,我为我们正在检查的情况定义模式:存在 /foo1/bar1 和存在 /foo2/bar2 。通过这两个定义,我使用 anyOf 来表示 /foo1/bar1 不存在,或者 /foo2/bar2 是必需的。换句话说,/foo1/bar1 意味着 /foo2/bar2

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "foo1": {
      "type": [ "object" ],
      "properties": {
        "bar1": { "type": "string" }
      }
    },
    "foo2": {
      "type": [ "object" ],
      "properties": {
        "bar2": { "type": "string" }
      }
    }
  },
  "allOf": [{ "$ref": "#/definitions/foo1-bar1-implies-foo2-bar2" }],
  "dependencies": {
    "foo1": ["foo2"]
  },
  "definitions": {
    "foo1-bar1-implies-foo2-bar2": {
      "anyOf": [
        { "not": { "$ref": "#/definitions/foo1-bar1" } },
        { "$ref": "#/definitions/foo2-bar2" }
      ]
    },
    "foo1-bar1": {
      "properties": {
        "foo1": { "required": ["bar1"] }
      },
      "required": ["foo1"]
    },
    "foo2-bar2": {
      "properties": {
        "foo2": { "required": ["bar2"] }
      },
      "required": ["foo2"]
    }
  }
}

关于node.js - 如何声明嵌套属性的依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49285921/

相关文章:

node.js - 本地主机上的 MongoDB SSL 是否是必需的?

javascript - Node.js,获取找不到模块 'ws'错误

json - JSON模式属性取决于先前属性的值

javascript - NodeJS Ajv 模块总是记录消息 ' $ref: keywords ignored in schema at path "#"'

javascript - 如何使用 Ajv 编译 JSON 架构的子集?

node.js - 在Elasticsearch 6x中何处添加索引缓冲区大小

javascript - multi或upsert设置为true后,MongoDB不更新记录并且promise保持失败

Golang invopop jsonschema if/then/else 的用法

json - 如何在 JSON 模式中扩展模式?

jsonschema - 如何在 JSON Schema 中使用来自外部文件的定义?