Add support for ISO 3166 to validator (#1967)

* Add ISO 3166 support

* Add support for ISO-3166

* Add changelog

* Test fixes
This commit is contained in:
James Agnew 2020-07-06 05:29:48 -04:00 committed by GitHub
parent 6fb6675b1e
commit 4b1546f002
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 461 additions and 801 deletions

View File

@ -0,0 +1,5 @@
---
type: add
issue: 1967
title: The HAPI FHIR CommonCodeSystemsTerminologyService validation support module now
includes support for ISO 3166 (country codes).

View File

@ -98,6 +98,15 @@ The following table lists vocabulary that is validated by this module:
added in the future, please get in touch if you would like to help.
</td>
</tr>
<tr>
<td>Countries (ISO 3166)</td>
<td>
CodeSystem: <a href="urn:iso:std:iso:3166">urn:iso:std:iso:3166</a>
</td>
<td>
Codes are validated against a built-in list of valid ISO 3166 codes. Both Alpha-2 (two character) and Alpha-3 (three character) variants are supported.
</td>
</tr>
<tr>
<td>Unified Codes for Units of Measure (UCUM)</td>
<td>

View File

@ -1,7 +1,6 @@
package org.hl7.fhir.common.hapi.validation.support;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.support.ConceptValidationOptions;
import ca.uhn.fhir.context.support.IValidationSupport;
import ca.uhn.fhir.context.support.ValidationSupportContext;
@ -189,11 +188,24 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
case MIMETYPES_CODESYSTEM_URL:
// This is a pretty naive implementation - Should be enhanced in future
LookupCodeResult mimeRetVal = new LookupCodeResult();
mimeRetVal.setSearchedForCode(theCode);
mimeRetVal.setSearchedForSystem(theSystem);
mimeRetVal.setFound(true);
return mimeRetVal;
case CURRENCIES_CODESYSTEM_URL:
String currenciesDisplay = ISO_3166_CODES.get(theCode);
if (isNotBlank(currenciesDisplay)) {
LookupCodeResult retVal = new LookupCodeResult();
retVal.setSearchedForCode(theCode);
retVal.setSearchedForSystem(theSystem);
retVal.setFound(true);
retVal.setCodeDisplay(currenciesDisplay);
return retVal;
}
break;
default:
@ -528,6 +540,8 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
private static HashMap<String, String> buildIso3166Codes() {
HashMap<String, String> codes = new HashMap<>();
// 2 letter codes
codes.put("AF", "Afghanistan");
codes.put("AX", "Åland Islands");
codes.put("AL", "Albania");
@ -777,6 +791,257 @@ public class CommonCodeSystemsTerminologyService implements IValidationSupport {
codes.put("YE", "Yemen");
codes.put("ZM", "Zambia");
codes.put("ZW", "Zimbabwe");
// 3 letter codes
codes.put("ABW", "Aruba");
codes.put("AFG", "Afghanistan");
codes.put("AGO", "Angola");
codes.put("AIA", "Anguilla");
codes.put("ALA", "Åland Islands");
codes.put("ALB", "Albania");
codes.put("AND", "Andorra");
codes.put("ARE", "United Arab Emirates");
codes.put("ARG", "Argentina");
codes.put("ARM", "Armenia");
codes.put("ASM", "American Samoa");
codes.put("ATA", "Antarctica");
codes.put("ATF", "French Southern Territories");
codes.put("ATG", "Antigua and Barbuda");
codes.put("AUS", "Australia");
codes.put("AUT", "Austria");
codes.put("AZE", "Azerbaijan");
codes.put("BDI", "Burundi");
codes.put("BEL", "Belgium");
codes.put("BEN", "Benin");
codes.put("BES", "Bonaire, Sint Eustatius and Saba");
codes.put("BFA", "Burkina Faso");
codes.put("BGD", "Bangladesh");
codes.put("BGR", "Bulgaria");
codes.put("BHR", "Bahrain");
codes.put("BHS", "Bahamas");
codes.put("BIH", "Bosnia and Herzegovina");
codes.put("BLM", "Saint Barthélemy");
codes.put("BLR", "Belarus");
codes.put("BLZ", "Belize");
codes.put("BMU", "Bermuda");
codes.put("BOL", "Bolivia, Plurinational State of");
codes.put("BRA", "Brazil");
codes.put("BRB", "Barbados");
codes.put("BRN", "Brunei Darussalam");
codes.put("BTN", "Bhutan");
codes.put("BVT", "Bouvet Island");
codes.put("BWA", "Botswana");
codes.put("CAF", "Central African Republic");
codes.put("CAN", "Canada");
codes.put("CCK", "Cocos (Keeling) Islands");
codes.put("CHE", "Switzerland");
codes.put("CHL", "Chile");
codes.put("CHN", "China");
codes.put("CIV", "Côte d'Ivoire");
codes.put("CMR", "Cameroon");
codes.put("COD", "Congo, the Democratic Republic of the");
codes.put("COG", "Congo");
codes.put("COK", "Cook Islands");
codes.put("COL", "Colombia");
codes.put("COM", "Comoros");
codes.put("CPV", "Cabo Verde");
codes.put("CRI", "Costa Rica");
codes.put("CUB", "Cuba");
codes.put("CUW", "Curaçao");
codes.put("CXR", "Christmas Island");
codes.put("CYM", "Cayman Islands");
codes.put("CYP", "Cyprus");
codes.put("CZE", "Czechia");
codes.put("DEU", "Germany");
codes.put("DJI", "Djibouti");
codes.put("DMA", "Dominica");
codes.put("DNK", "Denmark");
codes.put("DOM", "Dominican Republic");
codes.put("DZA", "Algeria");
codes.put("ECU", "Ecuador");
codes.put("EGY", "Egypt");
codes.put("ERI", "Eritrea");
codes.put("ESH", "Western Sahara");
codes.put("ESP", "Spain");
codes.put("EST", "Estonia");
codes.put("ETH", "Ethiopia");
codes.put("FIN", "Finland");
codes.put("FJI", "Fiji");
codes.put("FLK", "Falkland Islands (Malvinas)");
codes.put("FRA", "France");
codes.put("FRO", "Faroe Islands");
codes.put("FSM", "Micronesia, Federated States of");
codes.put("GAB", "Gabon");
codes.put("GBR", "United Kingdom");
codes.put("GEO", "Georgia");
codes.put("GGY", "Guernsey");
codes.put("GHA", "Ghana");
codes.put("GIB", "Gibraltar");
codes.put("GIN", "Guinea");
codes.put("GLP", "Guadeloupe");
codes.put("GMB", "Gambia");
codes.put("GNB", "Guinea-Bissau");
codes.put("GNQ", "Equatorial Guinea");
codes.put("GRC", "Greece");
codes.put("GRD", "Grenada");
codes.put("GRL", "Greenland");
codes.put("GTM", "Guatemala");
codes.put("GUF", "French Guiana");
codes.put("GUM", "Guam");
codes.put("GUY", "Guyana");
codes.put("HKG", "Hong Kong");
codes.put("HMD", "Heard Island and McDonald Islands");
codes.put("HND", "Honduras");
codes.put("HRV", "Croatia");
codes.put("HTI", "Haiti");
codes.put("HUN", "Hungary");
codes.put("IDN", "Indonesia");
codes.put("IMN", "Isle of Man");
codes.put("IND", "India");
codes.put("IOT", "British Indian Ocean Territory");
codes.put("IRL", "Ireland");
codes.put("IRN", "Iran, Islamic Republic of");
codes.put("IRQ", "Iraq");
codes.put("ISL", "Iceland");
codes.put("ISR", "Israel");
codes.put("ITA", "Italy");
codes.put("JAM", "Jamaica");
codes.put("JEY", "Jersey");
codes.put("JOR", "Jordan");
codes.put("JPN", "Japan");
codes.put("KAZ", "Kazakhstan");
codes.put("KEN", "Kenya");
codes.put("KGZ", "Kyrgyzstan");
codes.put("KHM", "Cambodia");
codes.put("KIR", "Kiribati");
codes.put("KNA", "Saint Kitts and Nevis");
codes.put("KOR", "Korea, Republic of");
codes.put("KWT", "Kuwait");
codes.put("LAO", "Lao People's Democratic Republic");
codes.put("LBN", "Lebanon");
codes.put("LBR", "Liberia");
codes.put("LBY", "Libya");
codes.put("LCA", "Saint Lucia");
codes.put("LIE", "Liechtenstein");
codes.put("LKA", "Sri Lanka");
codes.put("LSO", "Lesotho");
codes.put("LTU", "Lithuania");
codes.put("LUX", "Luxembourg");
codes.put("LVA", "Latvia");
codes.put("MAC", "Macao");
codes.put("MAF", "Saint Martin (French part)");
codes.put("MAR", "Morocco");
codes.put("MCO", "Monaco");
codes.put("MDA", "Moldova, Republic of");
codes.put("MDG", "Madagascar");
codes.put("MDV", "Maldives");
codes.put("MEX", "Mexico");
codes.put("MHL", "Marshall Islands");
codes.put("MKD", "Macedonia, the former Yugoslav Republic of");
codes.put("MLI", "Mali");
codes.put("MLT", "Malta");
codes.put("MMR", "Myanmar");
codes.put("MNE", "Montenegro");
codes.put("MNG", "Mongolia");
codes.put("MNP", "Northern Mariana Islands");
codes.put("MOZ", "Mozambique");
codes.put("MRT", "Mauritania");
codes.put("MSR", "Montserrat");
codes.put("MTQ", "Martinique");
codes.put("MUS", "Mauritius");
codes.put("MWI", "Malawi");
codes.put("MYS", "Malaysia");
codes.put("MYT", "Mayotte");
codes.put("NAM", "Namibia");
codes.put("NCL", "New Caledonia");
codes.put("NER", "Niger");
codes.put("NFK", "Norfolk Island");
codes.put("NGA", "Nigeria");
codes.put("NIC", "Nicaragua");
codes.put("NIU", "Niue");
codes.put("NLD", "Netherlands");
codes.put("NOR", "Norway");
codes.put("NPL", "Nepal");
codes.put("NRU", "Nauru");
codes.put("NZL", "New Zealand");
codes.put("OMN", "Oman");
codes.put("PAK", "Pakistan");
codes.put("PAN", "Panama");
codes.put("PCN", "Pitcairn");
codes.put("PER", "Peru");
codes.put("PHL", "Philippines");
codes.put("PLW", "Palau");
codes.put("PNG", "Papua New Guinea");
codes.put("POL", "Poland");
codes.put("PRI", "Puerto Rico");
codes.put("PRK", "Korea, Democratic People's Republic of");
codes.put("PRT", "Portugal");
codes.put("PRY", "Paraguay");
codes.put("PSE", "Palestine, State of");
codes.put("PYF", "French Polynesia");
codes.put("QAT", "Qatar");
codes.put("REU", "Réunion");
codes.put("ROU", "Romania");
codes.put("RUS", "Russian Federation");
codes.put("RWA", "Rwanda");
codes.put("SAU", "Saudi Arabia");
codes.put("SDN", "Sudan");
codes.put("SEN", "Senegal");
codes.put("SGP", "Singapore");
codes.put("SGS", "South Georgia and the South Sandwich Islands");
codes.put("SHN", "Saint Helena, Ascension and Tristan da Cunha");
codes.put("SJM", "Svalbard and Jan Mayen");
codes.put("SLB", "Solomon Islands");
codes.put("SLE", "Sierra Leone");
codes.put("SLV", "El Salvador");
codes.put("SMR", "San Marino");
codes.put("SOM", "Somalia");
codes.put("SPM", "Saint Pierre and Miquelon");
codes.put("SRB", "Serbia");
codes.put("SSD", "South Sudan");
codes.put("STP", "Sao Tome and Principe");
codes.put("SUR", "Suriname");
codes.put("SVK", "Slovakia");
codes.put("SVN", "Slovenia");
codes.put("SWE", "Sweden");
codes.put("SWZ", "Swaziland");
codes.put("SXM", "Sint Maarten (Dutch part)");
codes.put("SYC", "Seychelles");
codes.put("SYR", "Syrian Arab Republic");
codes.put("TCA", "Turks and Caicos Islands");
codes.put("TCD", "Chad");
codes.put("TGO", "Togo");
codes.put("THA", "Thailand");
codes.put("TJK", "Tajikistan");
codes.put("TKL", "Tokelau");
codes.put("TKM", "Turkmenistan");
codes.put("TLS", "Timor-Leste");
codes.put("TON", "Tonga");
codes.put("TTO", "Trinidad and Tobago");
codes.put("TUN", "Tunisia");
codes.put("TUR", "Turkey");
codes.put("TUV", "Tuvalu");
codes.put("TWN", "Taiwan, Province of China");
codes.put("TZA", "Tanzania, United Republic of");
codes.put("UGA", "Uganda");
codes.put("UKR", "Ukraine");
codes.put("UMI", "United States Minor Outlying Islands");
codes.put("URY", "Uruguay");
codes.put("USA", "United States of America");
codes.put("UZB", "Uzbekistan");
codes.put("VAT", "Holy See");
codes.put("VCT", "Saint Vincent and the Grenadines");
codes.put("VEN", "Venezuela, Bolivarian Republic of");
codes.put("VGB", "Virgin Islands, British");
codes.put("VIR", "Virgin Islands, U.S.");
codes.put("VNM", "Viet Nam");
codes.put("VUT", "Vanuatu");
codes.put("WLF", "Wallis and Futuna");
codes.put("WSM", "Samoa");
codes.put("YEM", "Yemen");
codes.put("ZAF", "South Africa");
codes.put("ZMB", "Zambia");
codes.put("ZWE", "Zimbabwe");
return codes;
}

View File

@ -30,6 +30,7 @@ import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
@ -184,9 +185,6 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
IBaseResource system = null;
if (!theOptions.isInferSystem() && isNotBlank(theCodeSystem)) {
system = theValidationSupportContext.getRootValidationSupport().fetchCodeSystem(theCodeSystem);
if (system == null) {
return null;
}
}
List<VersionIndependentConcept> codes = new ArrayList<>();
@ -265,9 +263,9 @@ public class InMemoryTerminologyServerValidationSupport implements IValidationSu
boolean codeMatches;
if (caseSensitive) {
codeMatches = theCode.equals(nextExpansionCode.getCode());
codeMatches = defaultString(theCode).equals(nextExpansionCode.getCode());
} else {
codeMatches = theCode.equalsIgnoreCase(nextExpansionCode.getCode());
codeMatches = defaultString(theCode).equalsIgnoreCase(nextExpansionCode.getCode());
}
if (codeMatches) {
if (theOptions.isInferSystem() || nextExpansionCode.getSystem().equals(theCodeSystem)) {

View File

@ -328,6 +328,36 @@ public class FhirInstanceValidatorDstu3Test {
return retVal;
}
@Test
public void testValidateWithIso3166() throws IOException {
loadNL();
FhirValidator val = ourCtx.newValidator();
val.registerValidatorModule(new FhirInstanceValidator(myValidationSupport));
// Code in VS
{
Patient p = loadResource("/dstu3/nl/nl-core-patient-instance.json", Patient.class);
ValidationResult result = val.validateWithResult(p);
List<SingleValidationMessage> all = logResultsAndReturnNonInformationalOnes(result);
assertTrue(result.isSuccessful());
assertThat(all, empty());
}
// Code not in VS
{
Patient p = loadResource("/dstu3/nl/nl-core-patient-instance-invalid-country.json", Patient.class);
ValidationResult result = val.validateWithResult(p);
assertFalse(result.isSuccessful());
List<SingleValidationMessage> all = logResultsAndReturnAll(result);
assertEquals(1, all.size());
assertEquals(ResultSeverityEnum.ERROR, all.get(0).getSeverity());
assertEquals("Validation failed for \"urn:iso:std:iso:3166#QQ\"", all.get(0).getMessage());
}
}
/**
* See #873
*/
@ -727,8 +757,20 @@ public class FhirInstanceValidatorDstu3Test {
@Test
public void testValidateUsingDifferentialProfile() throws IOException {
loadValueSet("/dstu3/nl/2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1--20171231000000.json");
loadNL();
Patient resource = loadResource("/dstu3/nl/nl-core-patient-01.json", Patient.class);
ValidationResult results = myVal.validateWithResult(resource);
List<SingleValidationMessage> outcome = logResultsAndReturnNonInformationalOnes(results);
assertThat(outcome.toString(), containsString("The Coding provided is not in the value set http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1--20171231000000"));
}
private void loadNL() throws IOException {
loadValueSet("/dstu3/nl/2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1--20171231000000.json");
loadValueSet("/dstu3/nl/LandGBACodelijst-2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1--20171231000000.json");
loadValueSet("/dstu3/nl/LandISOCodelijst-2.16.840.1.113883.2.4.3.11.60.40.2.20.5.2--20171231000000.json");
loadStructureDefinition("/dstu3/nl/extension-code-specification.json");
loadStructureDefinition("/dstu3/nl/nl-core-patient.json");
loadStructureDefinition("/dstu3/nl/proficiency.json");
loadStructureDefinition("/dstu3/nl/zibpatientlegalstatus.json");
@ -752,12 +794,6 @@ public class FhirInstanceValidatorDstu3Test {
loadStructureDefinition("/dstu3/nl/nl-core-practitioner.json");
loadStructureDefinition("/dstu3/nl/nl-core-relatedperson-role.json");
loadStructureDefinition("/dstu3/nl/PractitionerRoleReference.json");
Patient resource = loadResource("/dstu3/nl/nl-core-patient-01.json", Patient.class);
ValidationResult results = myVal.validateWithResult(resource);
List<SingleValidationMessage> outcome = logResultsAndReturnNonInformationalOnes(results);
assertThat(outcome.toString(), containsString("Element matches more than one slice"));
}
public void loadValueSet(String theFilename) throws IOException {

View File

@ -0,0 +1,55 @@
{
"resourceType": "ValueSet",
"id": "2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1--20171231000000",
"meta": {
"profile": [
"http://hl7.org/fhir/StructureDefinition/shareablevalueset"
]
},
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/resource-effectivePeriod",
"valuePeriod": {
"start": "2017-12-31T00:00:00+02:00"
}
}
],
"url": "http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1--20171231000000",
"identifier": [
{
"use": "official",
"system": "http://art-decor.org/ns/oids/vs",
"value": "2.16.840.1.113883.2.4.3.11.60.40.2.20.5.1"
}
],
"version": "2017-12-31T00:00:00",
"name": "LandGBACodelijst",
"title": "LandGBACodelijst",
"status": "active",
"experimental": false,
"publisher": "Registratie aan de bron",
"contact": [
{
"name": "Registratie aan de bron",
"telecom": [
{
"system": "url",
"value": "https://www.registratieaandebron.nl"
},
{
"system": "url",
"value": "https://zibs.nl"
}
]
}
],
"description": "GBA Tabel 34 (Landentabel) - Alle waarden",
"immutable": false,
"compose": {
"include": [
{
"system": "urn:oid:2.16.840.1.113883.2.4.4.16.34"
}
]
}
}

View File

@ -0,0 +1 @@
{"resourceType":"ValueSet","id":"2.16.840.1.113883.2.4.3.11.60.40.2.20.5.2--20171231000000","meta":{"profile":["http://hl7.org/fhir/StructureDefinition/shareablevalueset"]},"extension":[{"url":"http://hl7.org/fhir/StructureDefinition/resource-effectivePeriod","valuePeriod":{"start":"2017-12-31T00:00:00+02:00"}}],"url":"http://decor.nictiz.nl/fhir/ValueSet/2.16.840.1.113883.2.4.3.11.60.40.2.20.5.2--20171231000000","identifier":[{"use":"official","system":"http://art-decor.org/ns/oids/vs","value":"2.16.840.1.113883.2.4.3.11.60.40.2.20.5.2"}],"version":"2017-12-31T00:00:00","name":"LandISOCodelijst","title":"LandISOCodelijst","status":"active","experimental":false,"publisher":"Registratie aan de bron","contact":[{"name":"Registratie aan de bron","telecom":[{"system":"url","value":"https://www.registratieaandebron.nl"},{"system":"url","value":"https://zibs.nl"}]}],"description":"ISO 3166-1 (alpha-2) - Alle waarden","immutable":false,"compose":{"include":[{"system":"urn:iso:std:iso:3166"}]}}

View File

@ -0,0 +1 @@
{"resourceType":"StructureDefinition","id":"code-specification","url":"http://nictiz.nl/fhir/StructureDefinition/code-specification","version":"1.0.2","name":"Zib extension code specification","title":"HCIM extension code-specification","status":"active","publisher":"Nictiz","contact":[{"name":"Nictiz","telecom":[{"system":"email","value":"info@nictiz.nl","use":"work"}]}],"description":"Provides the specific HCIM code for a FHIR element that has a required binding to a FHIR ValueSet.","copyright":"CC0","fhirVersion":"3.0.2","kind":"complex-type","abstract":false,"contextType":"datatype","context":["code","Coding","CodeableConcept","Address.country"],"type":"Extension","baseDefinition":"http://hl7.org/fhir/StructureDefinition/Extension","derivation":"constraint","differential":{"element":[{"id":"Extension","path":"Extension","short":"Provides the specific HCIM code for a FHIR element that has a required binding to a FHIR ValueSet","definition":"Defines a more specific coded value for a code or string. Especially useful for FHIR's required ValueSets. These extensions are primarily used on codes bound to a required value set, where you would like to use a more specific code than the codes in the bounded value set.","alias":["Bevat de specifieke code conform de zib, bij een FHIR-element die een verplichte koppeling heeft met een bepaalde FHIR waardelijst of een FHIR element die niet gecodeerd is gedefinieerd, terwijl de zib dit wel doet."]},{"id":"Extension.url","path":"Extension.url","fixedUri":"http://nictiz.nl/fhir/StructureDefinition/code-specification"},{"id":"Extension.value[x]:valueCodeableConcept","path":"Extension.valueCodeableConcept","sliceName":"valueCodeableConcept","min":1,"type":[{"code":"CodeableConcept"}]}]}}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,36 @@
{
"resourceType": "Patient",
"id": "2725779",
"meta": {
"versionId": "1",
"lastUpdated": "2020-06-29T14:52:07.137+00:00",
"profile": [
"http://fhir.nl/fhir/StructureDefinition/nl-core-patient"
]
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table class=\"hapiPropertyTable\"><tbody><tr><td>Address</td><td><span>NLD </span></td></tr></tbody></table></div>"
},
"address": [
{
"country": "NLD",
"_country": {
"extension": [
{
"id": "LandISOCodelijst",
"url": "http://nictiz.nl/fhir/StructureDefinition/code-specification",
"valueCodeableConcept": {
"coding": [
{
"system": "urn:iso:std:iso:3166",
"code": "QQ"
}
]
}
}
]
}
}
]
}

View File

@ -0,0 +1,36 @@
{
"resourceType": "Patient",
"id": "2725779",
"meta": {
"versionId": "1",
"lastUpdated": "2020-06-29T14:52:07.137+00:00",
"profile": [
"http://fhir.nl/fhir/StructureDefinition/nl-core-patient"
]
},
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table class=\"hapiPropertyTable\"><tbody><tr><td>Address</td><td><span>NLD </span></td></tr></tbody></table></div>"
},
"address": [
{
"country": "NLD",
"_country": {
"extension": [
{
"id": "LandISOCodelijst",
"url": "http://nictiz.nl/fhir/StructureDefinition/code-specification",
"valueCodeableConcept": {
"coding": [
{
"system": "urn:iso:std:iso:3166",
"code": "NL"
}
]
}
}
]
}
}
]
}