///------------------------------------------------------------------------------------------------- /// <summary>Gets JSON type from element.</summary> /// /// <remarks>Gino Canessa, 8/12/2019.</remarks> /// /// <param name="def">The definition.</param> /// /// <returns>The JSON type from element.</returns> ///------------------------------------------------------------------------------------------------- private static string GetJsonTypeFromElement(fhir.ElementDefinition def) { // **** **** foreach (fhir.ElementDefinitionType type in def.Type) { if ((type.Extension != null) && (type.Extension.Length > 0)) { foreach (fhir.Extension ext in type.Extension) { if (ext.Url.EndsWith("fhir-type")) { return(ext.ValueUrl ?? ext.ValueUri); } } } // **** check for the json extension on the coding **** if ((type._Code != null) && (type._Code.Extension != null) && (type._Code.Extension.Length > 0)) { // **** find the correct one **** foreach (fhir.Extension ext in type._Code.Extension) { if (ext.Url.EndsWith("json-type")) { // **** return this type **** return(ext.ValueString); } } } } // **** all else fails, default to string **** return("string"); }
///------------------------------------------------------------------------------------------------- /// <summary>Process the structure type.</summary> /// /// <remarks>Gino Canessa, 8/20/2019.</remarks> /// /// <param name="sd"> The SD.</param> /// <param name="filename">Filename of the file.</param> ///------------------------------------------------------------------------------------------------- static void ProcessStructureType(fhir.StructureDefinition sd, string filename) { // **** figure out if this is a derived type **** string baseType = GetJsonTypeFromStructure(sd); if (string.IsNullOrEmpty(baseType)) { // **** use the base type **** baseType = sd.Type; } // **** reformat circular references **** if (baseType.Equals(sd.Id, StringComparison.Ordinal)) { baseType = ""; } // **** traverse the elements **** for (int elementIndex = 0; elementIndex < sd.Snapshot.Element.Length; elementIndex++) { fhir.ElementDefinition element = sd.Snapshot.Element[elementIndex]; // **** check for initial element (need to change type) **** if (elementIndex == 0) { // **** use the base type **** FhirTypeManager.ProcessSpreadsheetDataElement( sd.Name, baseType, sd.Description, $"{element.Min}..{element.Max}", false, filename ); // **** check for defining a base type **** if (!element.Id.Equals(sd.Name, StringComparison.Ordinal)) { // **** make sure this node exists too **** FhirTypeManager.ProcessSpreadsheetDataElement( element.Id, element.Base.Path, element.Definition, $"{element.Min}..{element.Max}", false, filename ); } // **** no more processing for this entry **** continue; } // **** check for inherited property **** if ((element.Base != null) && (!string.IsNullOrEmpty(element.Base.Path)) && (!element.Base.Path.Equals(element.Id, StringComparison.Ordinal))) { // **** skip this **** continue; } // **** check for type information **** if ((element.Type != null) && (element.Type.Length > 0) && (element.Type[0].Code != null)) { // **** grab the valueSet if present **** string valueSet = ""; if ((element.Binding != null) && (!string.IsNullOrEmpty(element.Binding.ValueSet))) { valueSet = element.Binding.ValueSet; } string cardinality = element.Type.Length > 1 ? "0..1" : $"{element.Min}..{element.Max}"; // **** traverse the types for this element **** foreach (ElementDefinitionType defType in element.Type) { string typeCode = defType.Code; // **** check for the FHIR Type extension **** if ((defType.Extension != null) && (defType.Extension.Length > 0)) { foreach (Extension ext in defType.Extension) { if (ext.Url.Equals( "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type", StringComparison.Ordinal)) { typeCode = ext.ValueUrl ?? ext.ValueUri; } } } // **** remove array info from name (if necessary) **** string elementName = element.Path.Replace( "[x]", string.Concat( typeCode.Substring(0, 1).ToUpper(), typeCode.Substring(1) ) ); // **** check for a code type **** if (typeCode == "code") { string[] codeValues = element.Short.Split('|'); // **** process this field **** FhirTypeManager.ProcessSpreadsheetDataElement( elementName, typeCode, (element.Comment == null) ? element.Definition : element.Comment, $"{element.Min}..{element.Max}", false, filename, codeValues ); // **** done with this field **** continue; } // **** process this field **** FhirTypeManager.ProcessSpreadsheetDataElement( elementName, typeCode, element.Definition, cardinality, false, filename, valueSet: valueSet ); } } // **** check for extension type information **** else if ((element.Type != null) && (element.Type.Length > 0) && (element.Type[0].Extension != null)) { // **** find the json type **** string propertyType = ""; foreach (Extension ext in element.Type[0].Extension) { if (ext.Url.EndsWith("fhir-type")) { propertyType = ext.ValueUrl ?? ext.ValueUri; break; } } // **** process this field **** FhirTypeManager.ProcessSpreadsheetDataElement( element.Path, propertyType, element.Definition, $"{element.Min}..{element.Max}", false, filename ); } // **** check for extension type information **** else if ((element.Type != null) && (element.Type.Length > 0) && (element.Type[0]._Code != null)) { // **** find the json type **** string propertyType = ""; foreach (Extension ext in element.Type[0]._Code.Extension) { if (ext.Url.EndsWith("json-type")) { propertyType = ext.ValueString; break; } } // **** process this field **** FhirTypeManager.ProcessSpreadsheetDataElement( element.Path, propertyType, element.Definition, $"{element.Min}..{element.Max}", false, filename ); } // **** use base path **** else { // **** grab the assumed type **** string propertyType = ""; // **** check for override **** if (!string.IsNullOrEmpty(element.ContentReference)) { propertyType = FhirPathToCamelCase(element.ContentReference); } // **** assume base path if nothing else filled out **** if (string.IsNullOrEmpty(propertyType)) { propertyType = FhirPathToCamelCase(element.Base.Path); } // **** process this field **** FhirTypeManager.ProcessSpreadsheetDataElement( element.Path, propertyType, element.Definition, $"{element.Min}..{element.Max}", false, filename ); } } }