コード例 #1
0
        /// <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>());
            }
        }
コード例 #3
0
        /// <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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #7
0
/*
 *      /// <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);
        }
コード例 #8
0
        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));
            }
        }