Reputation: 1
I'm working with the hl7 FHIR json schemas and there are pretty simple and lacking in some logic that I'd rather not write code for. There are properties that are mutually exclusive but are not required and I'm trying to find the best way to represent that in the json schema.
Let's take this one for example, specifically this part:
"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"
}
I was able to get it done but it's tedious and long. I don't mind doing it, but I was wondering if there was a simpler way.
Here's what I got:
"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"]}
}
]
}
}
Any ideas/solutions? There's another one like this in the same json schema so the dependencies are pretty long and the other schemas have more that just 5 properties to choose from.
Thanks!
Upvotes: 0
Views: 2627
Reputation: 3141
You can try using the "dependencies"
, "not"
and "required"
to solve this. So for example, to express that "if onsetAge is present then onsetPeriod and onsetRange should not be present" you can do the following:
{
"dependencies": {
"onsetAge": {
"allOf": [
{"not": {"required": ["onsetPeriod"]}},
{"not": {"required": ["onsetRange"]}}
]
}
}
}
(I didn't test it, just an idea)
Upvotes: 0
Reputation: 893
Glad you're finding the FHIR Json Schemas to be of use!
So, a couple things... the Json Schema that you're pointing to aren't the most up-to-date. They're on the official site as part of STU3; but the most recent version is from the Jan 2018 Working Group, and has a bunch of updates and fixes, and uses a new all-in-one format to resolve circular dependencies and other $ref issues. Get the latest at either of the following links.
http://build.fhir.org/fhir.schema.json.zip
https://www.npmjs.com/package/fhir-schemas
You are right though... there's still room for improvement. And, happily, it's an active area of development right now, and these kinds of improvements are have a good chance of getting incorporated into the official schemas.
So, taking a look at the problem you propose, we may be able to get some better milage out of oneOf
and possibly anyOf
. Based on the most recent version of the Condition resource, I'd try something like the following:
{
"Condition": {
"description": "A clinical condition, problem, diagnosis...",
"properties": {
"resourceType": {
"const": "Condition"
},
"id": {...},
"meta": {...},
"oneOf": [
"onsetDateTime": {...},
"_onsetDateTime": {...},
"onsetAge": {...},
"onsetPeriod": {...},
"onsetRange": {...},
"onsetString": {...},
"_onsetString": {...}
]
}
}
}
It may be as simple as wrapping the onset*
fields in an oneOf
array.
Upvotes: 1