/// <summary> /// Advance the navigator to the first reslice of the current named slice. /// Skip any existing child elements and/or child reslicing constraints. /// Otherwise remain positioned at the current element. /// </summary> /// <returns><c>true</c> if succesful, <c>false</c> otherwise.</returns> public static bool MoveToFirstReslice(this ElementDefinitionNavigator nav) { if (nav == null) { throw Error.ArgumentNull(nameof(nav)); } if (nav.Current == null) { throw Error.Argument(nameof(nav), "Cannot move navigator to previous slice. Current node is not set."); } var sliceName = nav.Current.Name; if (string.IsNullOrEmpty(sliceName)) { throw Error.Argument(nameof(nav), "The current element is not a named slice."); } var bm = nav.Bookmark(); if (nav.MoveToNextSliceAtAnyLevel()) { if (ElementDefinitionNavigator.IsResliceOf(nav.Current.Name, sliceName)) { return(true); } } // No match, restore original position nav.ReturnToBookmark(bm); return(false); }
private static IEnumerable <Bookmark> locateChildren(ElementDefinitionNavigator nav, IEnumerable <string> path, bool partial) { Debug.Assert(nav != null); // Caller should validate var child = path.First(); var rest = path.Skip(1); var bm = nav.Bookmark(); if (nav.MoveToChild(child)) { var result = new List <Bookmark>(); do { if (!rest.Any()) { // Exact match! result.Add(nav.Bookmark()); } else if (!nav.HasChildren && partial) { // This is as far as we can get in this structure, // so this is a hit too if partial hits are OK result.Add(nav.Bookmark()); } else { // So, no hit, but we have children that might fit the bill. result.AddRange(locateChildren(nav, rest, partial)); } // Try this for the other matching siblings too... }while (nav.MoveToNext(child)); // We've scanned all my children and collected the results, // move the navigator back to where we were before nav.ReturnToBookmark(bm); return(result); } else { return(Enumerable.Empty <Bookmark>()); } }
/// <summary> /// Enumerate any succeeding direct child slices of the specified element. /// Skip any intermediate child elements and re-slice elements. /// When finished, return the navigator to the initial position. /// </summary> /// <param name="intro"></param> /// <param name="atRoot">Specify <c>true</c> for finding direct (simple) slices, or <c>false</c> for finding re-slices.</param> /// <returns>A sequence of <see cref="Bookmark"/> instances.</returns> internal static IEnumerable <Bookmark> FindMemberSlices(this ElementDefinitionNavigator intro, bool atRoot) { var bm = intro.Bookmark(); var path = intro.Current.Path; var pathName = intro.PathName; var name = intro.Current.Name; while (intro.MoveToNext(pathName)) { var curName = intro.Current.Name; if (atRoot) { // Is this the slice-intro of the un-resliced original element? Then my name == null or // (in DSTU2) my name has no slicing separator (since name is used both for slicing and // re-use of constraints, e.g. Composition.section.name, just == null is not enough) // I am the root slice, my slices would be the unnamed slices (though this is strictly seen not correct, every slice needs a name) // and every slice with a non-resliced name if (curName == null) { yield return(intro.Bookmark()); } if (!ElementDefinitionNavigator.IsResliceName(curName)) { yield return(intro.Bookmark()); } } else { // Else, if I am a named slice, I am a slice myself, but also the intro to a nested re-sliced group, // so include only my children in my group... if (ElementDefinitionNavigator.IsResliceOf(curName, name)) { yield return(intro.Bookmark()); } } // Else...there might be something wrong, I need to add logic here to find slices that are out of // order, of have a resliced name that does not start with the last slice intro we found. } intro.ReturnToBookmark(bm); }
/// <summary> /// Advance the navigator forward to the slicing constraint in the current slice group with the specified slice name. /// Otherwise remain positioned at the current element. /// </summary> /// <returns><c>true</c> if succesful, <c>false</c> otherwise.</returns> public static bool MoveToNextSliceAtAnyLevel(this ElementDefinitionNavigator nav, string sliceName) { var bm = nav.Bookmark(); while (nav.MoveToNextSliceAtAnyLevel()) { if (StringComparer.Ordinal.Equals(nav.Current.Name, sliceName)) { return(true); } } nav.ReturnToBookmark(bm); return(false); }
public static bool DeleteChildren(this ElementDefinitionNavigator nav) { var parent = nav.Bookmark(); if (nav.MoveToFirstChild()) { while (!nav.IsAtBookmark(parent)) { nav.DeleteTree(); } } return(true); }
// [WMR 20160802] NEW /// <summary>Move the navigator to the first preceding sibling element with the specified name, if it exists.</summary> /// <returns><c>true</c> if succesful, <c>false</c> otherwise.</returns> public static bool MoveToPrevious(this ElementDefinitionNavigator nav, string name) { if (nav == null) { throw Error.ArgumentNull(nameof(nav)); } var bm = nav.Bookmark(); while (nav.MoveToPrevious()) { if (nav.PathName == name) { return(true); } } nav.ReturnToBookmark(bm); return(false); }
/* * /// <summary> * /// If the current element is a slice entry, then advance the navigator to the first associated named slice. * /// Otherwise remain positioned at the current element. * /// </summary> * /// <returns><c>true</c> if succesful, <c>false</c> otherwise.</returns> * public static bool MoveToFirstSlice(this ElementDefinitionNavigator nav) * { * if (nav == null) { throw Error.ArgumentNull(nameof(nav)); } * if (nav.Current == null) { throw Error.Argument(nameof(nav), "Cannot move navigator to previous slice. Current node is not set."); } * if (nav.Current.Slicing != null) * { * var bm = nav.Bookmark(); * if (nav.MoveToNextSliceAtAnyLevel()) { return true; } * nav.ReturnToBookmark(bm); * } * return false; * } */ /// <summary> /// Advance the navigator to the next slice in the current slice group and on the current slicing level. /// Skip any existing child elements and/or child reslicing constraints. /// Otherwise remain positioned at the current element. /// </summary> /// <returns><c>true</c> if succesful, <c>false</c> otherwise.</returns> public static bool MoveToNextSlice(this ElementDefinitionNavigator nav) { if (nav == null) { throw Error.ArgumentNull(nameof(nav)); } if (nav.Current == null) { throw Error.Argument(nameof(nav), "Cannot move navigator to next slice. Current node is not set."); } var bm = nav.Bookmark(); var name = nav.PathName; var startSliceName = nav.Current.Name; var startBaseSliceName = ElementDefinitionNavigator.GetBaseSliceName(startSliceName); while (nav.MoveToNext(name)) { var sliceName = nav.Current.Name; // Handle unnamed slices, eg. extensions if (startSliceName == null && sliceName == null) { return(true); } if (ElementDefinitionNavigator.IsSiblingSliceOf(startSliceName, sliceName)) { return(true); } if (startBaseSliceName != null && sliceName.Length > startBaseSliceName.Length && !sliceName.StartsWith(startBaseSliceName)) { break; } } // No match, restore original position nav.ReturnToBookmark(bm); return(false); }
private static void rebaseChildren(ElementDefinitionNavigator nav, string path, List <string> newPaths) { var bm = nav.Bookmark(); if (nav.MoveToFirstChild()) { do { var newPath = path + "." + nav.Current.GetNameFromPath(); newPaths.Add(newPath); if (nav.HasChildren) { rebaseChildren(nav, newPath, newPaths); } }while (nav.MoveToNext()); nav.ReturnToBookmark(bm); } }
public static IEnumerable <Bookmark> Approach(this ElementDefinitionNavigator nav, string path) { if (nav == null) { throw Error.ArgumentNull(nameof(nav)); } if (path == null) { throw Error.ArgumentNull(nameof(path)); } var parts = path.Split('.'); var bm = nav.Bookmark(); nav.Reset(); var result = locateChildren(nav, parts, partial: true); nav.ReturnToBookmark(bm); return(result); }
public static bool AppendChild(this ElementDefinitionNavigator nav, ElementDefinition child) { var bm = nav.Bookmark(); if (nav.MoveToFirstChild()) { while (nav.MoveToNext()) { ; } var result = nav.InsertAfter(child); if (!result) { nav.ReturnToBookmark(bm); } return(result); } else { return(nav.InsertFirstChild(child)); } }