public static bool ExpandElement(this ElementNavigator nav, StructureLoader source) { if(source == null) throw Error.ArgumentNull("source"); if(nav.Current == null) throw Error.ArgumentNull("Navigator is not positioned on an element"); if (nav.Current.Definition == null) throw Error.Argument("Cannot move down into element {0} since it has no element definition information", nav.Path); if(nav.HasChildren) return true; // already has children, we're not doing anything extra if (nav.Current.Definition != null) { var defn = nav.Current.Definition; if (!String.IsNullOrEmpty(defn.NameReference)) { var sourceNav = resolveNameReference(nav.Structure, defn.NameReference); nav.CopyChildren(sourceNav); } else if (defn.Type != null && defn.Type.Count > 0) { if (defn.Type.Count > 1) throw new NotImplementedException("Don't know how to implement navigation into choice types yet at node " + nav.Path); else { var sourceNav = resolveStructureReference(source, defn.Type[0].CodeElement); if (sourceNav != null) { sourceNav.MoveToFirstChild(); nav.CopyChildren(sourceNav); } else throw new FileNotFoundException("Cannot locate base-structure for datatype " + defn.Type[0].Code); } } return true; } return false; }
/// <summary> /// Insert the children of the current source node under the node pointed to by the destination. /// </summary> /// <param name="dest"></param> /// <param name="source"></param> /// <returns></returns> public static bool CopyChildren(this BaseElementNavigator dest, ElementNavigator source) { if (dest.HasChildren) return false; // Protect children from being overwritten if (!source.MoveToFirstChild()) return true; // Nothing to copy, but successful anyway bool firstChild = true; do { var copiedChild = (Profile.ElementComponent)source.Current.DeepCopy(); if (firstChild) { // The first time, create a new child in the destination dest.InsertFirstChild(copiedChild); firstChild = false; } else // Then insert other childs after that dest.InsertAfter(copiedChild); // If there are nested children in the source, insert them under // the newly inserted node in the destination if (source.HasChildren) dest.CopyChildren(source); } while (source.MoveToNext()); // Bring both source & destination back one step to the original parents source.MoveToParent(); dest.MoveToParent(); return true; }
public static bool ExpandElement(this ElementNavigator nav, ArtifactResolver source) { if (source == null) throw Error.ArgumentNull("source"); if (nav.Current == null) throw Error.ArgumentNull("Navigator is not positioned on an element"); if (nav.HasChildren) return true; // already has children, we're not doing anything extra var defn = nav.Current; if (!String.IsNullOrEmpty(defn.NameReference)) { var sourceNav = new ElementNavigator(nav); var success = sourceNav.JumpToNameReference(defn.NameReference); if(!success) throw Error.InvalidOperation("Trying to navigate down a node that has a nameReference of '{0}', which cannot be found in the StructureDefinition".FormatWith(defn.NameReference)); nav.CopyChildren(sourceNav); } else if (defn.Type != null && defn.Type.Count > 0) { if (defn.Type.Count > 1) throw new NotSupportedException("Element at path {0} has a choice of types, cannot expand".FormatWith(nav.Path)); else { var coreType = source.GetStructureDefinitionForCoreType(defn.Type[0].Code); if (coreType == null) throw Error.NotSupported("Trying to navigate down a node that has a declared base type of '{0}', which is unknown".FormatWith(defn.Type[0].Code)); if (coreType.Snapshot == null) throw Error.NotSupported("Found definition of base type '{0}', but is does not contain a snapshot representation".FormatWith(defn.Type[0].Code)); var sourceNav = new ElementNavigator(coreType.Snapshot.Element); sourceNav.MoveToFirstChild(); nav.CopyChildren(sourceNav); } } return true; }