/// <summary>Harvest the value of a child element into a property bag.</summary>
 /// <param name="nav">An <see cref="IElementNavigator"/> instance.</param>
 /// <param name="properties">A property bag to store harvested summary information.</param>
 /// <param name="key">A property key.</param>
 /// <param name="element">An element name.</param>
 /// <param name="childElement">A child element name.</param>
 public static bool HarvestValue(this IElementNavigator nav, IDictionary <string, object> properties, string key, string element, string childElement)
 {
     if (nav.Find(element))
     {
         var childNav = nav.Clone();
         return(childNav.MoveToFirstChild(childElement) && childNav.HarvestValue(properties, key));
     }
     return(false);
 }
        /// <summary>Harvest extension values into a property bag.</summary>
        /// <param name="nav">An <see cref="IElementNavigator"/> instance.</param>
        /// <param name="properties">A property bag to store harvested summary information.</param>
        /// <param name="extensionValueHarvester">Callback function called for each individual extension entry.</param>
        public static void HarvestExtensions(this IElementNavigator nav, IDictionary <string, object> properties, Action <IElementNavigator, IDictionary <string, object>, string> extensionValueHarvester)
        {
            const string extension = "extension";

            if (nav.Find(extension))
            {
                do
                {
                    var childNav = nav.Clone();
                    if (childNav.MoveToFirstChild("url"))

                    {
                        if (childNav.Value is string url)
                        {
                            extensionValueHarvester(childNav, properties, url);
                        }
                    }
                    // [WMR 20171219] BUG: MoveToNext advances to extension.url (child attribute) instead of the next extension element
                } while (nav.MoveToNext(extension));
            }
        }
 /// <summary>Harvest an array of child element values into a property bag.</summary>
 /// <param name="nav">An <see cref="IElementNavigator"/> instance.</param>
 /// <param name="properties">A property bag to store harvested summary information.</param>
 /// <param name="key">A property key.</param>
 /// <param name="element">An element name.</param>
 /// <param name="childElement">A child element name.</param>
 public static bool HarvestValues(this IElementNavigator nav, IDictionary <string, object> properties, string key, string element, string childElement)
 {
     if (nav.Find(element))
     {
         var values = new List <string>();
         do
         {
             var childNav = nav.Clone();
             if (childNav.MoveToFirstChild(childElement))
             {
                 HarvestValue(childNav, values);
             }
         } while (nav.MoveToNext(element));
         if (values.Count > 0)
         {
             properties[key] = values.ToArray();
             return(true);
         }
     }
     return(false);
 }
 /// <summary>Harvest the value of the (current or sibling) element with the specified name into a property bag.</summary>
 /// <param name="nav">An <see cref="IElementNavigator"/> instance.</param>
 /// <param name="properties">A property bag to store harvested summary information.</param>
 /// <param name="key">A property key.</param>
 /// <param name="element">An element name.</param>
 public static bool HarvestValue(this IElementNavigator nav, IDictionary <string, object> properties, string key, string element)
 {
     return(nav.Find(element) && nav.HarvestValue(properties, key));
 }