/// <summary> /// Returns if Slice is same as this slice, false otherwise. /// </summary> public bool SameAs(ElementTreeSlice other) { if ((this.ElementDefinition != null) || (other.ElementDefinition != null)) { if ((this.ElementDefinition == null) || (other.ElementDefinition == null)) { return(false); } if (this.ElementDefinition.IsExactly(other.ElementDefinition) == false) { return(false); } } if (this.Nodes.Count != other.Nodes.Count) { return(false); } for (Int32 index = 0; index < this.Nodes.Count; index++) { ElementTreeNode thisNode = this.Nodes.GetItemAt(index); ElementTreeNode otherNode = other.Nodes.GetItemAt(index); if (thisNode.SameAs(otherNode) == false) { return(false); } } return(true); }
void SliceOid(String sliceName, String shortText, Markdown definition, out ElementTreeSlice extensionSlice, out ElementTreeNode valueXNode ) { Self.Slice(e, extensionNode, sliceName, shortText, definition, out extensionSlice, out valueXNode ); valueXNode.ElementDefinition .Type("oid") .Single() ; e.AddComponentLink(sliceName.ToMachineName(), new SDefEditor.Cardinality(extensionSlice.ElementDefinition), null, Global.ElementAnchor(extensionSlice.ElementDefinition), "Oid"); }
public ElementTreeNode SliceValueXByType(ElementTreeSlice slice, String[] types) { ElementDefinition valueX = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.value[x]", ElementId = $"{slice.ElementDefinition.ElementId}.value[x]", Min = 1, Max = "1" }; valueX .Types(types) ; ElementDefinition.SlicingComponent slicingComponent = new ElementDefinition.SlicingComponent { Rules = ElementDefinition.SlicingRules.Closed }; slicingComponent.Discriminator.Add(new ElementDefinition.DiscriminatorComponent { Type = ElementDefinition.DiscriminatorType.Type, Path = "$this" }); valueX.ApplySlicing(slicingComponent, false); return(slice.CreateNode(valueX)); }
ElementTreeSlice SliceSection(ElementTreeNode sliceElementDef, String sliceName, String title, Coding code, out ElementDefinition entry) { ElementTreeSlice slice = sliceElementDef.CreateSlice(sliceName); CreateElement(slice, "title") .Single() .Fixed(new FhirString(title)) ; CreateElement(slice, "code") .Single() .Pattern(code.ToCodeableConcept().ToPattern()) .DefaultValueExtension(code.ToCodeableConcept()) ; CreateElement(slice, "focus") .Zero() ; entry = CreateElement(slice, "entry") ; CreateElement(slice, "section") .Zero() ; return(slice); }
public ElementTreeSlice ApplyExtension(ElementTreeNode extDef, String name, String extensionUrl) { String sliceName = name.UncapFirstLetter(); this.ConfigureSliceByUrlDiscriminator(extDef, true); ElementTreeSlice slice = extDef.CreateSlice(sliceName); slice.ElementDefinition.Min = 0; slice.ElementDefinition.Max = "*"; slice.ElementDefinition .SetShort($"{name} extension.") .SetDefinition(new Markdown() .Paragraph($"This extension slice contains the {name} extension.")) .SetComment(ResourcesMaker.componentDefinition) ; slice.ElementDefinition.IsModifier = false; slice.ElementDefinition.Type.Add(new ElementDefinition.TypeRefComponent { Code = "Extension", Profile = new String[] { extensionUrl } }); return(slice); }
public BuildMemberExtensionSimple(DefineBase defineBase, ClassCodeBlocks codeBlocks, ElementTreeSlice extensionSlice, String extensionName) : base(defineBase, codeBlocks) { this.extensionSlice = extensionSlice; this.extensionName = extensionName; }
public BuildMemberExtension(DefineBase defineBase, ClassCodeBlocks codeBlocks, ElementTreeSlice extensionSlice, String extensionName) { this.extensionName = extensionName; this.defineBase = defineBase; this.codeBlocks = codeBlocks; this.extensionSlice = extensionSlice; }
void BuildExtension(ElementTreeSlice extensionSlice) { this.itemCodeBlocks.LocalUsings = this.codeBlocks.LocalUsings; BuildMemberExtension bme = new BuildMemberExtension(this.defineBase, this.itemCodeBlocks, extensionSlice, extensionSlice.ElementDefinition.SliceName.ToMachineName()); bme.Build(); }
public void SliceComponentSize(String sliceName, CodeableConcept componentCode, ValueSet units, Int32 min, String max, out ElementTreeSlice slice) { slice = this.AppendSlice("component", sliceName, min, max); this.SliceComponentCode(slice, sliceName, componentCode); SliceSize(slice, units); }
ElementDefinition CreateElement(ElementTreeSlice slice, String name) { ElementDefinition e = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.{name}", ElementId = $"{slice.ElementDefinition.ElementId}.{name}" }; slice.CreateNode(e); return(e); }
/// <summary> /// Clone /// </summary> public ElementTreeSlice Clone(ElementTreeNode parent) { ElementDefinition e = (ElementDefinition)this.ElementDefinition?.DeepCopy(); ElementTreeSlice retVal = new ElementTreeSlice(parent, this.Name, e); foreach (ElementTreeNode node in this) { retVal.Nodes.Add(node.Clone()); } return(retVal); }
public ElementDefinition SliceSelfByPattern(String path, String sliceName, Element pattern) { ElementTreeNode elementDef = ApplySliceSelf(path); sliceName = sliceName.UncapFirstLetter(); ElementTreeSlice codingSlice = elementDef.CreateSlice(sliceName); codingSlice.ElementDefinition.Pattern = pattern; return(codingSlice.ElementDefinition); }
public ElementTreeSlice AppendSlice(String elementName, String sliceName, Int32 min = 0, String max = "*") { ElementTreeNode elementDef = this.Get(elementName); ElementTreeSlice retVal = elementDef.CreateSlice(sliceName); retVal.ElementDefinition.Min = min; retVal.ElementDefinition.Max = max; return(retVal); }
public void SliceSize(ElementTreeSlice slice, ValueSet units) { // Fix component code ElementTreeNode valueXNode = this.SliceValueXByType(slice, new string[] { "Quantity", "Range" }); { Hl7.Fhir.Model.Quantity q = new Hl7.Fhir.Model.Quantity { System = units.Url }; ElementDefinition valueX = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.value[x]", ElementId = $"{slice.ElementDefinition.ElementId}.value[x]:valueQuantity", SliceName = $"valueQuantity", Min = 0, Max = "1" } .Pattern(q) .Type("Quantity") ; valueXNode.CreateSlice($"valueQuantity", valueX); } { Hl7.Fhir.Model.Range r = new Hl7.Fhir.Model.Range { Low = new SimpleQuantity { System = units.Url, }, High = new SimpleQuantity { System = units.Url, } }; ElementDefinition valueX = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.value[x]", ElementId = $"{slice.ElementDefinition.ElementId}.value[x]:valueRange", SliceName = $"valueRange", Min = 0, Max = "1" } .Pattern(r) .Type("Range") ; valueXNode.CreateSlice($"valueRange", valueX); } }
bool MergeElementTreeSlice(ElementTreeSlice baseSlice, ElementTreeSlice mergeSlice) { const String fcn = "MergeElementTreeSlice"; bool retVal = true; foreach (ElementTreeNode mergeNode in mergeSlice.Nodes) { ElementTreeNode baseNode = null; if (!baseSlice.Nodes.TryGetItem(mergeNode.Name, out baseNode)) { // see if element definition is something like {CodeableConcept}.coding. if ( (baseItem.SnapNodeOriginal.TryGetElementNode(baseSlice.ElementDefinition.Path, out ElementTreeNode originalNode) == false) || (this.IsElementPart(originalNode.ElementDefinition, mergeNode.Name) == false) ) { this.preFhir.ConversionError(this.GetType().Name, fcn, $"Node '{mergeNode.Path}' does not exist in base. Can not add element to non-fragment"); return(false); } if (this.preFhir.DebugFlag) { this.preFhir.ConversionInfo(this.GetType().Name, fcn, $"Node '{mergeNode.Path}' does not exist in base. Copying whole node"); } // Node doesnt exist in base, so copy it whole. baseNode = mergeNode.Clone(); baseNode.ReplaceBasePath(this.baseItem.BasePath); baseSlice.Nodes.Add(baseNode); } else { if (this.preFhir.DebugFlag) { this.preFhir.ConversionInfo(this.GetType().Name, fcn, $"Node '{mergeNode.Path}' found in base. Merging node"); } if (!MergeElementTreeNode(baseNode, mergeNode)) { retVal = false; } } } return(retVal); }
void Slice(SDefEditor e, ElementTreeNode extensionNode, String sliceName, String shortText, Markdown definition, out ElementTreeSlice extensionSlice, out ElementTreeNode valueXNode) { extensionSlice = extensionNode.CreateSlice(sliceName); extensionSlice.ElementDefinition .ElementId($"{extensionNode.ElementDefinition.Path}:{sliceName}") .SliceName(sliceName) .Short(shortText) .Definition(definition) .SetCardinality(0, "1") ; extensionSlice.ElementDefinition.Type = null; { ElementDefinition sealExtension = new ElementDefinition { ElementId = $"{extensionNode.ElementDefinition.Path}:{sliceName}.extension", Path = $"{extensionNode.ElementDefinition.Path}.extension" }; sealExtension.Zero(); extensionSlice.CreateNode(sealExtension); } { ElementDefinition elementUrl = new ElementDefinition() .Path($"{extensionNode.ElementDefinition.Path}.url") .ElementId($"{extensionNode.ElementDefinition.Path}:{sliceName}.url") .Value(new FhirUri(sliceName)) .Type("uri") .Definition(new Markdown() .Paragraph($"Url for {sliceName} complex extension item.") ) ; extensionSlice.CreateNode(elementUrl); } { ElementDefinition valueBase = e.Get("value[x]").ElementDefinition; ElementDefinition elementValue = new ElementDefinition() .Path($"{extensionNode.ElementDefinition.Path}.value[x]") .ElementId($"{extensionNode.ElementDefinition.Path}:{sliceName}.value[x]") ; valueXNode = extensionSlice.CreateNode(elementValue); } }
void SliceAndBindUrl(SDefEditor e, ElementTreeNode extensionNode, String sliceName, String bindName, String shortText, Markdown definition, out ElementTreeSlice extensionSlice, out ElementTreeNode valueXNode) { this.Slice(e, extensionNode, sliceName, shortText, definition, out extensionSlice, out valueXNode); valueXNode.ElementDefinition .Type("CodeableConcept") .Binding(bindName, BindingStrength.Required) .Single() ; }
public ElementTreeSlice SliceByUrlTarget(ElementTreeNode sliceElementDef, String profileUrl, Int32 min, String max) { String sliceName = profileUrl.LastUriPart().UncapFirstLetter(); ElementTreeSlice slice = sliceElementDef.CreateSlice(sliceName); slice.ElementDefinition.SetCardinality(min, max); slice.ElementDefinition.Type.Clear(); slice.ElementDefinition.Type.Add(new ElementDefinition.TypeRefComponent { Code = "Reference", TargetProfile = new String[] { profileUrl } }); return(slice); }
public ElementTreeNode SliceComponentCode(ElementTreeSlice slice, String sliceName, CodeableConcept sliceCode) { ElementDefinition componentCode = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.code", ElementId = $"{slice.ElementDefinition.Path}:{sliceName}.code", Min = 1, Max = "1" }; componentCode .Pattern(sliceCode.ToPattern()) .DefaultValueExtension(sliceCode) ; return(slice.CreateNode(componentCode)); }
public ElementTreeSlice SliceTargetReference(ElementTreeNode sliceElementDef, StructureDefinition profile, Int32 min = 0, String max = "*") { String baseName = sliceElementDef.ElementDefinition.Path.LastPathPart(); ElementTreeSlice retVal = this.SliceByUrlTarget(sliceElementDef, profile.Url, min, max); retVal.ElementDefinition .SetShort($"'{profile.Title}' reference.") .SetDefinition( new Markdown() .Paragraph($"This slice references the target '{profile.Title}'.") ) ; this.AddTargetLink(profile.Url.Trim(), new SDefEditor.Cardinality(retVal.ElementDefinition), false); return(retVal); }
void SortSlice(ElementTreeSlice orderTemplateSlice, ElementTreeSlice itemsSlice) { Dictionary <String, Int32> order = new Dictionary <string, int>(); ElementTreeNode[] orderNodes = orderTemplateSlice.Nodes.ToArray(); for (Int32 i = 0; i < orderTemplateSlice.Nodes.Count; i++) { order.Add(orderNodes[i].Name, i); } SortNodes(itemsSlice.Nodes.Items, order); foreach (ElementTreeNode node in itemsSlice.Nodes) { if (orderTemplateSlice.Nodes.TryGetItem(node.Name, out ElementTreeNode orderTemplateNode) == false) { throw new Exception($"{node.Path} not found in order template. Is node named incorrectly?"); } SortElements(orderTemplateNode, node); } }
void ProcessSlice(ElementTreeSlice originalDefaultSlice, ElementTreeSlice modifiedSlice) { //const String fcn = "ProcessSlice"; if ((originalDefaultSlice.ElementDefinition != null) && (modifiedSlice.ElementDefinition != null)) { modifiedSlice.ElementDefinition.Base = new ElementDefinition.BaseComponent { Path = originalDefaultSlice.ElementDefinition.Path, Min = originalDefaultSlice.ElementDefinition.Min, Max = originalDefaultSlice.ElementDefinition.Max }; } foreach (ElementTreeNode modifiedNode in modifiedSlice.Nodes.ToArray()) { if (originalDefaultSlice.Nodes.TryGetItem(modifiedNode.Name, out ElementTreeNode originalNode) == true) { ProcessNode(originalNode, modifiedNode); } } }
void ProcessSlice(ElementTreeSlice originalSlice, ElementTreeSlice modifiedSlice) { //const String fcn = "ProcessSlice"; if ((originalSlice.ElementDefinition != null) && (modifiedSlice.ElementDefinition != null)) { if (originalSlice.ElementDefinition.IsExactly(modifiedSlice.ElementDefinition)) { // Clear all fields except for Path and Id and SliceName ElementDefinition newE = new ElementDefinition { Path = modifiedSlice.ElementDefinition.Path, ElementId = modifiedSlice.ElementDefinition.ElementId, SliceName = modifiedSlice.ElementDefinition.SliceName }; modifiedSlice.ElementDefinition = newE; } else { ElementDefinition originalElement = originalSlice.ElementDefinition; ElementDefinition modifiedElement = modifiedSlice.ElementDefinition; modifiedElement.Base = new ElementDefinition.BaseComponent { Path = originalElement.Path, Min = originalElement.Min, Max = originalElement.Max }; if ((originalElement.Min == modifiedElement.Min) && (originalElement.Max == modifiedElement.Max)) { modifiedElement.Min = null; modifiedElement.Max = null; } modifiedElement.RepresentationElement = Compare.ClearIfSame(originalElement.RepresentationElement, modifiedElement.RepresentationElement); #if FHIR_R4 modifiedElement.SliceIsConstraining = Compare.ClearIfSame(originalElement.SliceIsConstraining, modifiedElement.SliceIsConstraining); #endif modifiedElement.Label = Compare.ClearIfSame(originalElement.Label, modifiedElement.Label); modifiedElement.Code = Compare.ClearIfSame(originalElement.Code, modifiedElement.Code); modifiedElement.Constraint = Compare.ClearIfSame(originalElement.Constraint, modifiedElement.Constraint); modifiedElement.Slicing = Compare.ClearIfSame(originalElement.Slicing, modifiedElement.Slicing); modifiedElement.Short = Compare.ClearIfSame(originalElement.Short, modifiedElement.Short); modifiedElement.Definition = Compare.ClearIfSame(originalElement.Definition, modifiedElement.Definition); modifiedElement.Comment = Compare.ClearIfSame(originalElement.Comment, modifiedElement.Comment); modifiedElement.Requirements = Compare.ClearIfSame(originalElement.Requirements, modifiedElement.Requirements); modifiedElement.AliasElement = Compare.ClearIfSame(originalElement.AliasElement, modifiedElement.AliasElement); modifiedElement.ContentReference = Compare.ClearIfSame(originalElement.ContentReference, modifiedElement.ContentReference); modifiedElement.Type = Compare.ClearIfSame(originalElement.Type, modifiedElement.Type); modifiedElement.DefaultValue = Compare.ClearIfSame(originalElement.DefaultValue, modifiedElement.DefaultValue); modifiedElement.MeaningWhenMissing = Compare.ClearIfSame(originalElement.MeaningWhenMissing, modifiedElement.MeaningWhenMissing); modifiedElement.OrderMeaning = Compare.ClearIfSame(originalElement.OrderMeaning, modifiedElement.OrderMeaning); modifiedElement.Fixed = Compare.ClearIfSame(originalElement.Fixed, modifiedElement.Fixed); modifiedElement.Pattern = Compare.ClearIfSame(originalElement.Pattern, modifiedElement.Pattern); modifiedElement.Example = Compare.ClearIfSame(originalElement.Example, modifiedElement.Example); modifiedElement.MinValue = Compare.ClearIfSame(originalElement.MinValue, modifiedElement.MinValue); modifiedElement.MaxValue = Compare.ClearIfSame(originalElement.MaxValue, modifiedElement.MaxValue); modifiedElement.MaxLengthElement = Compare.ClearIfSame(originalElement.MaxLengthElement, modifiedElement.MaxLengthElement); modifiedElement.ConditionElement = Compare.ClearIfSame(originalElement.ConditionElement, modifiedElement.ConditionElement); modifiedElement.ConditionElement = Compare.ClearIfSame(originalElement.ConditionElement, modifiedElement.ConditionElement); modifiedElement.MustSupportElement = Compare.ClearIfSame(originalElement.MustSupportElement, modifiedElement.MustSupportElement); modifiedElement.IsModifierElement = Compare.ClearIfSame(originalElement.IsModifierElement, modifiedElement.IsModifierElement); #if FHIR_R4 modifiedElement.IsModifierReasonElement = Compare.ClearIfSame(originalElement.IsModifierReasonElement, modifiedElement.IsModifierReasonElement); #endif modifiedElement.IsSummaryElement = Compare.ClearIfSame(originalElement.IsSummaryElement, modifiedElement.IsSummaryElement); modifiedElement.Binding = Compare.ClearIfSame(originalElement.Binding, modifiedElement.Binding); modifiedElement.Mapping = Compare.ClearIfSame(originalElement.Mapping, modifiedElement.Mapping); } } foreach (ElementTreeNode modifiedNode in modifiedSlice.Nodes.ToArray()) { if (originalSlice.Nodes.TryGetItem(modifiedNode.Name, out ElementTreeNode originalNode) == true) { if (originalNode.SameAs(modifiedNode) == true) { modifiedSlice.Nodes.Remove(modifiedNode); } else { // Slices are different. Drill down.... ProcessNode(originalNode, modifiedNode); } } } }
/// <summary> /// Wildly recursive. Be carefull! /// </summary> void Load(String path, ElementTreeSlice headSlice, ElementDefinition[] loadItems, ref Int32 itemIndex) { const String fcn = "Load"; while (itemIndex < loadItems.Length) { ElementDefinition loadItem = loadItems[itemIndex]; if (loadItem.Path.Length <= path.Length) { return; } if (loadItem.Path.StartsWith(path) == false) { return; } if ((path.Length > 0) && (loadItem.Path[path.Length] != '.')) { return; } String newPath = path; if (newPath.Length > 0) { newPath += "."; } String loadPath = loadItem.Path.Substring(newPath.Length); String[] parts = loadPath.Split('.'); newPath += parts[0]; if (parts.Length > 1) { if (headSlice.Nodes.TryGetItem(parts[0], out ElementTreeNode childNode) == false) { this.Info(this.GetType().Name, fcn, $"Creating undefined node {newPath}"); childNode = headSlice.CreateNode(newPath, parts[0], null); } Load(newPath, childNode.DefaultSlice, loadItems, ref itemIndex); } else if (parts.Length == 1) { if (headSlice.Nodes.TryGetItem(parts[0], out ElementTreeNode childNode) == false) { if (String.IsNullOrEmpty(loadItem.SliceName)) { childNode = headSlice.CreateNode(newPath, parts[0], loadItem); headSlice.AddAliases(childNode, loadItem); } else { childNode = headSlice.CreateNode(newPath, parts[0], null); headSlice.AddAliases(childNode, loadItem); } } ElementTreeSlice childSlice; if (String.IsNullOrEmpty(loadItem.SliceName)) { childSlice = childNode.DefaultSlice; } else { childSlice = childNode.CreateSlice(loadItem.SliceName, loadItem); } itemIndex += 1; Load(newPath, childSlice, loadItems, ref itemIndex); } } }
public static String FhirPath(ElementTreeSlice slice) { return(slice.ElementDefinition.ElementId); }
public ElementTreeSlice ComponentSliceCodeableConcept(String sliceName, CodeableConcept pattern, ValueSet valueSet, BindingStrength bindingStrength, Int32 minCardinality, String maxCardinality, String componentName, String sliceDefinitionText, Modalities modalities = Modalities.All) { String compStr = maxCardinality == "1" ? compStr = "component" : "components"; Markdown sliceDefinition; { String introStr; if (minCardinality == 0) { if (maxCardinality == "1") { introStr = "This slice contains the optional component"; } else { introStr = "This slice contains the optional components"; } } else { if (maxCardinality == "1") { introStr = "This slice contains the required component"; } else { introStr = "This slice contains the required components"; } } sliceDefinition = new Markdown() .Paragraph($"{introStr} that {sliceDefinitionText}.", $"The value of this component is a codeable concept chosen from the {valueSet.Name} valueset."); } ElementTreeSlice slice = this.AppendSlice("component", sliceName, minCardinality, maxCardinality); slice.ElementDefinition .SetShort($"{componentName} component.") .SetDefinition(sliceDefinition) .SetComment(ResourcesMaker.componentDefinition) ; if (modalities != Modalities.All) { slice.ElementDefinition.Definition .ValidModalities(modalities); } if (String.IsNullOrWhiteSpace(pattern.Coding[0].Display)) { throw new Exception($"Display null on coding {pattern.Coding[0].Code}"); } { ElementDefinition componentCode = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.code", ElementId = $"{slice.ElementDefinition.Path}:{sliceName}.code", Min = 1, Max = "1", Short = $"{componentName} component code", Definition = new Markdown() .Paragraph($"This code identifies the {componentName} {compStr}.", $"Its value shall always be the concept '{pattern.Coding[0].Display}'") }; componentCode .Pattern(pattern.ToPattern()) .DefaultValueExtension(pattern) ; slice.CreateNode(componentCode); } { ElementDefinition valueX = new ElementDefinition { Path = $"{slice.ElementDefinition.Path}.value[x]", ElementId = $"{slice.ElementDefinition.Path}:{sliceName}.value[x]", Min = 1, Max = "1", Short = $"{componentName} component value", }; valueX .Binding(valueSet, bindingStrength) .Type("CodeableConcept") .SetDefinition(new Markdown() .Paragraph("Value is a codeable concept.") ) ; slice.CreateNode(valueX); } String componentRef = Global.ElementAnchor(slice.ElementDefinition); this.AddComponentLink(componentName, new SDefEditor.Cardinality(slice.ElementDefinition), null, componentRef, "CodeableConcept", valueSet.Url); return(slice); }