//private static void mergeStructure(Profile.ConstraintComponent snapshot, Profile.ConstraintComponent differential) //{ // if (differential.Name != null) snapshot.Name = differential.Name; // if (differential.Publish != null) snapshot.Publish = differential.Publish; // if (differential.Purpose != null) snapshot.Purpose = differential.Purpose; //} private void merge(ElementNavigator snap, ElementNavigator diff) { mergeElementAttributes(snap.Current, diff.Current); // If there are children, move into them, and recursively merge them if (diff.MoveToFirstChild()) { if (!snap.HasChildren) { // The differential moves into an element that has no children in the base. // This is allowable if the base's element has a nameReference or a TypeRef, // in which case needs to be expanded before we can move to the path indicated // by the differential expandBaseElement(snap, diff); } // Due to how MoveToFirstChild() works, we have to move to the first matching *child* // when entering the loop for the first time, after that we can look for the next // matching *sibling*. bool firstEntry = true; do { if( (firstEntry && !snap.MoveToChild(diff.PathName)) || (!firstEntry && !snap.MoveToNext(diff.PathName)) ) throw Error.InvalidOperation("Differential has a constraint for path '{0}', which does not exist in its base", diff.PathName); firstEntry = false; // Child found in both, merge them if (countChildNameRepeats(diff) > 1 || diff.Current.IsExtension()) { // The child in the diff repeats or we recognize it as an extension slice -> we're on the first element of a slice! mergeSlice(snap, diff); } else merge(snap, diff); } while (diff.MoveToNext()); // After the merge, return the diff and snapho back to their original position diff.MoveToParent(); snap.MoveToParent(); } }
private void merge(ElementNavigator snap, ElementNavigator diff) { (new ElementDefnMerger(_markChanges)).Merge(snap.Current, diff.Current); // If there are children, move into them, and recursively merge them if (diff.MoveToFirstChild()) { if (!snap.HasChildren) { // The differential moves into an element that has no children in the base. // This is allowable if the base's element has a nameReference or a TypeRef, // in which case needs to be expanded before we can move to the path indicated // by the differential if (snap.Current.Type.Count > 1) throw new NotSupportedException("Differential has a constraint on a choice element {0}, but does so without using a type slice".FormatWith(diff.Path)); expandBaseElement(snap, diff); } // Due to how MoveToFirstChild() works, we have to move to the first matching *child* // when entering the loop for the first time, after that we can look for the next // matching *sibling*. bool firstEntry = true; do { if ((firstEntry && !snap.MoveToChild(diff.PathName)) || (!firstEntry && !snap.MoveTo(diff.PathName)) ) // HACK: I don't think it should be allowed for a diff to list constraints in the wrong order... { throw Error.InvalidOperation("Differential has a constraint for path '{0}', which does not exist in its base", diff.Path); } firstEntry = false; // Child found in both, merge them if (countChildNameRepeats(diff) > 1 || diff.Current.IsExtension()) { // The child in the diff repeats or we recognize it as an extension slice -> we're on the first element of a slice! mergeSlice(snap, diff); } else merge(snap, diff); } while (diff.MoveToNext()); // After the merge, return the diff and snapho back to their original position diff.MoveToParent(); snap.MoveToParent(); } }