public void TestElementUsePropertyFromBase() { string sourcePath = Configuration.GetValue <string>("sourcePath"); string outputPath = Configuration.GetValue <string>("outputPath"); string canonicalBase = Configuration.GetValue <string>("defaults:baseurl"); string publisher = Configuration.GetValue <string>("defaults:publisher"); ScanResources processor = new ScanResources(sourcePath, outputPath, canonicalBase, publisher); var sd = processor.sourceSD.ResolveByCanonicalUri("http://hl7.org/fhir/StructureDefinition/Patient") as StructureDefinition; Assert.AreEqual(28, sd.Differential.Element.Count()); ElementDefinitionCollection edc = new ElementDefinitionCollection(processor.sourceSD, sd.Differential.Element.ToList()); Assert.AreEqual(28, edc.Elements.Count()); edc.IncludeElementFromBaseOrDatatype("Patient.telecom.system"); Assert.AreEqual(33, edc.Elements.Count()); edc.IncludeElementFromBaseOrDatatype("Patient.identifier.value"); Assert.AreEqual(39, edc.Elements.Count()); }
public void ScanForExtensions(string basePath, ITypedElement item, StructureDefinition sd) { string context = string.IsNullOrEmpty(basePath) ? item.Name : basePath + "." + item.Name; bool customSD = false; // Check for extensions var iv = item as IFhirValueProvider; if (iv.FhirValue is Extension) { // this is a child that is the extension itself... // and not doing complex extensions just yet return; } if (iv.FhirValue is Resource r) { var canonicalUri = $"{_outputProfileBaseUri}StructureDefinition/{r.TypeName}"; sd = sourceSD.ResolveByCanonicalUri(canonicalUri) as StructureDefinition; if (sd == null) { sd = CreateProfileWithAllMinZero($"http://hl7.org/fhir/StructureDefinition/{r.TypeName}", _outputProfileBaseUri); customSD = true; } } if (iv.FhirValue != null) { // Mark the property in the SD as in use, so not 0 anymore var ed = sd?.Differential?.Element.FirstOrDefault(e => e.Path == context || e.Path == context + "[x]"); if (ed != null) { ed.Max = null; ed.MustSupport = true; customSD = true; int usage = ed.IncrementUsage(); System.Diagnostics.Trace.WriteLine($" {context} updated {usage}"); if (usage == 1) { // Need to expand the datatype into the element table } } else { System.Diagnostics.Trace.WriteLine($" {context} not found"); ElementDefinitionCollection edc = new ElementDefinitionCollection(this.sourceSD, sd.Differential.Element.ToList()); edc.IncludeElementFromBaseOrDatatype(context); sd.Differential.Element = edc.Elements.ToList(); // replace the re-processed element tree ed = sd?.Differential?.Element.FirstOrDefault(e => e.Path == context); if (ed != null) { ed.Max = null; customSD = true; ed.MustSupport = true; int usage = ed.IncrementUsage(); System.Diagnostics.Trace.WriteLine($" {context} updated {usage}"); if (usage == 1) { // Need to expand the datatype into the element table } } } } if (iv.FhirValue is IExtendable extendable) { if (extendable.Extension != null) { foreach (var ext in extendable.Extension) { var instSD = sourceSD.ResolveByCanonicalUri(ext.Url) as StructureDefinition; if (instSD == null) { Console.WriteLine($" x==> Extension {ext.Url} not found"); System.Diagnostics.Trace.WriteLine($" x==> Extension {ext.Url} not found"); if (ext.Value != null) { DeriveExtensionFromUsage(ext.Url, ext.Value.TypeName, context); } } else { System.Diagnostics.Trace.WriteLine($" ---> Extension {ext.Url} exists"); // Check that this extension is defineed to support this if (ext.Value != null) { UpdateExtensionStructureDefinitionForUsage(instSD, ext.Value.TypeName, context); } } // Check that the extension is in the SD for this property var ed = sd.Differential.Element.FirstOrDefault(e => e.Path == context); if (ed != null) { // this is the position after which the extension needs to be added // check if it is already in there var edExts = sd.Differential.Element.Where(e => e.Path == context + ".extension"); if (!edExts.Any()) { // this is the position after which the extension needs to be added // check if it is already in there } Uri t = new Uri(ext.Url); if (!edExts.Any(e => e.SliceName == t.Segments.Last())) { var edExt = new ElementDefinition() { ElementId = $"{context}.extension:{t.Segments.Last()}", Path = context + ".extension", SliceName = t.Segments.Last(), MustSupport = true }; edExt.Type.Add(new ElementDefinition.TypeRefComponent() { Code = "Extension", Profile = new[] { ext.Url } }); sd.Differential.Element.Insert(sd.Differential.Element.IndexOf(ed) + 1, edExt); } } } } } var children = item.Children(); if (children != null) { foreach (var child in children) { var fv = child as IFhirValueProvider; if (fv.FhirValue is Resource rc) { ScanForExtensions(null, rc.ToTypedElement(), null); } else { ScanForExtensions(context, child, sd); } } } if (customSD) { SaveStructureDefinition(sd); } }