JSON Schema - 多个属性中的一个或不属性。更简单的方法?

时间:2018-02-20 21:30:39

标签: json jsonschema hl7-fhir

我正在使用hl7 FHIR json模式,并且非常简单,并且缺少某些逻辑,我宁愿不编写代码。有些属性是互斥但不是必需的,我正在尝试找到在json架构中表示的最佳方法。

我们以this one为例,特别是这部分:

"onsetDateTime": {
  "description": "Estimated or actual date or date-time  the condition 
  began, in the opinion of the clinician.",
  "pattern": "-?[0-9]{4}(-(0[1-9]|1[0-2])(-(0[0-9]|[1-2][0-9]|3[0-1])
  (T([01][0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9](\\.[0-9]+)?(Z|(\\+|-)
  ((0[0-9]|1[0-3]):[0-5][0-9]|14:00)))?)?)?",
  "type": "string"
},
"_onsetDateTime": {
  "description": "Extensions for onsetDateTime",
  "$ref": "Element.schema.json#/definitions/Element"
},
"onsetAge": {
  "description": "Estimated or actual date or date-time  the condition 
  began, in the opinion of the clinician.",
  "$ref": "Age.schema.json#/definitions/Age"
},
"onsetPeriod": {
  "description": "Estimated or actual date or date-time  the condition 
  began, in the opinion of the clinician.",
  "$ref": "Period.schema.json#/definitions/Period"
},
"onsetRange": {
  "description": "Estimated or actual date or date-time  the condition 
  began, in the opinion of the clinician.",
  "$ref": "Range.schema.json#/definitions/Range"
},
"onsetString": {
  "description": "Estimated or actual date or date-time  the condition 
  began, in the opinion of the clinician.",
  "type": "string"
},
"_onsetString": {
  "description": "Extensions for onsetString",
  "$ref": "Element.schema.json#/definitions/Element"
}
  • 一次不能有两个起始*属性。所以如果有startingDateTime,那么就不能有onsetAge,onsetPeriod,onsetRange或者startingString
  • 只有onsetString可以有_onsetString,只有onsetDateTime可以有_onsetDateTime但是它们都不需要出现
  • 不需要* *

我能够完成它,但它很乏味而且很长。我不介意这样做,但我想知道是否有更简单的方法。

这是我得到的:

"dependencies":
  "onsetDateTime": {
    "allOf": [
      {
        "not": {"required": ["onsetAge"]}
      },
      {
        "not": {"required": ["onsetPeriod"]}
      },
      {
        "not": {"required": ["onsetRange"]}
      },
      {
        "not": {"required": ["onsetString"]}
      },
      {
        "not": {"required": ["_onsetString"]}
      }
    ]
  },
  "onsetAge": {
    "allOf": [
      {
        "not": {"required": ["_onsetDateTime"]}
      },
      {
        "not": {"required": ["onsetPeriod"]}
      },
      {
        "not": {"required": ["onsetRange"]}
      },
      {
        "not": {"required": ["onsetString"]}
      },
      {
        "not": {"required": ["_onsetString"]}
      }
    ]
  },
  "onsetPeriod": {
    "allOf": [
      {
        "not": {"required": ["_onsetDateTime"]}
      },
      {
        "not": {"required": ["onsetRange"]}
      },
      {
        "not": {"required": ["onsetString"]}
      },
      {
        "not": {"required": ["_onsetString"]}
      }
    ]
  },
  "onsetRange": {
    "allOf": [
      {
        "not": {"required": ["_onsetDateTime"]}
      },
      {
        "not": {"required": ["onsetString"]}
      },
      {
        "not": {"required": ["_onsetString"]}
      }
    ]
  },
  "onsetString": {
    "allOf": [
      {
        "not": {"required": ["_onsetDateTime"]}
      }
    ]
  }
}

任何想法/解决方案?在同一个json模式中有另外一个这样的依赖关系很长,其他模式只有5个属性可供选择。

谢谢!

2 个答案:

答案 0 :(得分:1)

很高兴你发现FHIR Json Schemas有用!

所以,有几件事......你所指的Json Schema并不是最新的。他们作为STU3的一部分在官方网站上;但最新版本来自2018年1月的工作组,并有一堆更新和修复,并使用新的一体化格式来解决循环依赖和其他$ ref问题。通过以下任一链接获取最新信息。

http://build.fhir.org/fhir.schema.json.zip
https://www.npmjs.com/package/fhir-schemas

你是对的......但仍有改进的余地。而且,幸运的是,它现在是一个活跃的发展领域,这些改进很有可能被纳入官方模式。

所以,看看你提出的问题,我们可以从oneOfanyOf中获得更好的结果。根据最新版本的Condition资源,我会尝试以下内容:

{
  "Condition": {
    "description": "A clinical condition, problem, diagnosis...",
    "properties": {
      "resourceType": {
          "const": "Condition"
      },
      "id": {...},
      "meta": {...},
      "oneOf": [
        "onsetDateTime": {...},
        "_onsetDateTime": {...},
        "onsetAge": {...},
        "onsetPeriod": {...},
        "onsetRange": {...},
        "onsetString": {...},
        "_onsetString": {...}
      ]
    }
  }
}

可能就像在onset*数组中包装oneOf字段一样简单。

答案 1 :(得分:0)

您可以尝试使用"dependencies""not""required"来解决此问题。因此,例如,要表达"如果存在onsetAge,则不应存在onsetPeriod和onsetRange"你可以做到以下几点:

{
  "dependencies": {
    "onsetAge": {
      "allOf": [
        {"not": {"required": ["onsetPeriod"]}},
        {"not": {"required": ["onsetRange"]}}
      ]
    }
  }
}

(我没有测试它,只是一个想法)