private void GroupOpenSliceElements(SDTreeNode node) { if (node.IsSetupSlice && (!node.IsSetupSliceForExtension)) { List <SDTreeNode> nodesToGroup = new List <SDTreeNode>(); foreach (SDTreeNode childNode in node.Children) { if (!childNode.IsSlice) { nodesToGroup.Add(childNode); } } if (node.Element.slicing.rules.value == SlicingRuleslist.open) { ElementDefinition openSliceElement = new ElementDefinition(); openSliceElement.path = new @string(); openSliceElement.path.value = node.Element.path.value + "#n"; openSliceElement.name = new @string(); // openSliceElement.name.value = "open"; // also fix cardinalities openSliceElement.type = node.GetElementDefinitionType(); SDTreeNode openSlice = new SDTreeNode(openSliceElement); openSlice.AddChildren(nodesToGroup.ToArray()); node.AddChild(openSlice); } else if (node.Element.slicing.rules.value == SlicingRuleslist.openAtEnd) { ElementDefinition openAtEndSliceElement = new ElementDefinition(); openAtEndSliceElement.path = new @string(); openAtEndSliceElement.path.value = node.Element.path.value + "#n"; openAtEndSliceElement.name = new @string(); // openAtEndSliceElement.name.value = "openAtEnd"; // also fix cardinalities openAtEndSliceElement.type = node.GetElementDefinitionType(); SDTreeNode openAtEndSlice = new SDTreeNode(openAtEndSliceElement); openAtEndSlice.AddChildren(nodesToGroup.ToArray()); node.AddChild(openAtEndSlice); } else { foreach (SDTreeNode childNodeToRemove in nodesToGroup) { node.RemoveChild(childNodeToRemove); } } } }
private void AddMissingComplexDataTypeElements(SDTreeNode node) { StructureDefinition dataTypeDefinition; ElementDefinition dataTypeRootElement; ElementDefinition[] dataTypeChildElements; // if is element in multi level complex type, recall context if (multiLevelComplexTypeRevisit.ContainsKey(node)) { dataTypeDefinition = multiLevelComplexTypeRevisit[node].ComplexDataTypeDefinition; dataTypeRootElement = multiLevelComplexTypeRevisit[node].MultiLevelElementDefinition; dataTypeChildElements = dataTypeDefinition.differential.element.GetChildren(dataTypeRootElement).ToArray(); } else // else check whether is root of complex type { // don't expand profiles with multi choice types if (node.GetElementDefinitionType() == null) { return; } if (node.GetElementDefinitionType().Count() != 1) { return; } ElementDefinitionType elementType = node.GetElementDefinitionType().Single(); if (elementType == null) { return; } if (!(elementType.IsComplexType() || elementType.IsReference())) { return; } // don't expand root Extension elements if ((node.Path == "Extension") && (elementType.TypeName == "Element")) { return; } dataTypeDefinition = FhirData.Instance.FindDataTypeStructureDefinition(elementType.TypeName); if (dataTypeDefinition == null) { throw new Exception("Could not find FHIR data type " + elementType.TypeName); } dataTypeRootElement = dataTypeDefinition.differential.element.GetRootElement(); dataTypeChildElements = dataTypeDefinition.differential.element.GetChildren(dataTypeRootElement).ToArray(); } List <SDTreeNode> newChildren = new List <SDTreeNode>(); foreach (ElementDefinition dataTypeChildElement in dataTypeChildElements) { string lastPathElement = dataTypeChildElement.GetLastPathValue(); SDTreeNode[] existingChildren = node.Children.Where(t => t.LastPathElementWithoutSliceIndex == lastPathElement).ToArray(); List <SDTreeNode> currentNewChildren = new List <SDTreeNode>(); // if child or children don't exist, add the child if (existingChildren.Length == 0) { SDTreeNode newChild = new SDTreeNode(dataTypeChildElement); currentNewChildren.Add(newChild); } else // child or children already exists { foreach (SDTreeNode existingChild in existingChildren) { // if is a "fake" element, it needs replacing if (existingChild.Element.IsFake) { SDTreeNode newChild = new SDTreeNode(dataTypeChildElement); SDTreeNode[] childsChildren = existingChild.Children; existingChild.RemoveAllChildren(); newChild.AddChildren(childsChildren); currentNewChildren.Add(newChild); } else // keep the existing child { existingChild.Element.BaseElementDefinition = dataTypeChildElement; currentNewChildren.Add(existingChild); } } } newChildren.AddRange(currentNewChildren); // if complex data type's children have children....argh! (should only be for the Timing data type) if (dataTypeDefinition.differential.element.GetChildren(dataTypeChildElement).Count() > 0) { MultiLevelComplexTypePointer multiLevelComplexTypePointer = new MultiLevelComplexTypePointer() { ComplexDataTypeDefinition = dataTypeDefinition, MultiLevelElementDefinition = dataTypeChildElement }; foreach (SDTreeNode currentChild in currentNewChildren) { multiLevelComplexTypeRevisit.Add(currentChild, multiLevelComplexTypePointer); } } } foreach (SDTreeNode childNode in node.Children) { if (newChildren.All(t => t.LastPathElement != childNode.LastPathElement)) { newChildren.Add(childNode); } } node.RemoveAllChildren(); node.AddChildren(newChildren.ToArray()); }