///------------------------------------------------------------------------------------------------- /// <summary>Process the data elements table.</summary> /// /// <remarks>Gino Canessa, 7/8/2019.</remarks> /// /// <param name="dt"> The dt.</param> /// <param name="isPrimitive"> True if is primitive, false if not.</param> /// <param name="sourceFilename"> Filename of the source file.</param> /// <param name="firstElementName">[out] Name of the first element.</param> ///------------------------------------------------------------------------------------------------- static void ProcessDataElementsTable( DataTable dt, bool isPrimitive, string sourceFilename, out string firstElementName ) { // **** grab the indexes of the columns we care about **** int ordinalElement = dt.Columns["Element"].Ordinal; int ordinalCardinality = dt.Columns["Card."].Ordinal; int ordinalType = dt.Columns["Type"].Ordinal; int ordinalComment = dt.Columns["Definition"].Ordinal; int ordinalShortName = dt.Columns["Short Name"].Ordinal; // **** check for no rows **** if ((dt.Rows == null) || (dt.Rows.Count == 0)) { firstElementName = ""; return; } // **** grab the element name from the first row **** firstElementName = dt.Rows[0][ordinalElement].ToString(); // **** iterate over the items in this table **** foreach (DataRow row in dt.Rows) { // **** grab our data **** string element = row[ordinalElement].ToString(); string cardinality = row[ordinalCardinality].ToString(); string baseType = row[ordinalType].ToString(); string comment = row[ordinalComment].ToString(); // **** check for no comment (use short name) **** if (string.IsNullOrEmpty(comment)) { comment = row[ordinalShortName].ToString(); } // **** skip empty rows **** if (string.IsNullOrEmpty(element)) { continue; } // **** process this field **** FhirTypeManager.ProcessSpreadsheetDataElement(element, baseType, comment, cardinality, isPrimitive, sourceFilename); } }
///------------------------------------------------------------------------------------------------- /// <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 ); } } }