Beispiel #1
0
        /// <inheritdoc />
        public override IEnumerable <T> Execute(string query)
        {
            var navigator = _node.GetNavigator();

            var nodes = navigator.Select(query);

            var htmlElements =
                (from IXPathNavigable node in nodes select _page.ElementFactory.Create <T>(_page, node)).ToList();

            var radioButtonNames = new List <string>();

            // Radio buttons are expressed as multiple HTML tags, but need to be returned as a single HtmlRadioButton instance
            // The factory above has already created multiple instances based on the multiple nodes found
            // so we now need to find any radio buttons and filter out the duplicates
            // This is a little inefficient because there is the overhead of creating and initializing the radio button
            // multiple times however this code is much cleaner
            foreach (var element in htmlElements)
            {
                var radioButton = element as HtmlRadioButton;

                if (radioButton == null)
                {
                    // Not a radio button so no filtering is required
                    yield return(element);
                }
                else if (radioButtonNames.Contains(radioButton.Name) == false)
                {
                    radioButtonNames.Add(radioButton.Name);

                    yield return(element);
                }
            }
        }
        /// <summary>
        /// Determines whether the specified navigable has the specified attribute.
        /// </summary>
        /// <param name="navigable">
        /// The navigable.
        /// </param>
        /// <param name="name">
        /// The name.
        /// </param>
        /// <returns>
        /// <c>true</c> if the specified navigable has the attribute; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasAttribute(this IXPathNavigable navigable, string name)
        {
            var navigator = navigable.GetNavigator();

            var checkedFound = navigator.MoveToAttribute(name, string.Empty);

            return(checkedFound);
        }
        /// <summary>
        /// Builds the supported tags message.
        /// </summary>
        /// <param name="node">
        /// The node.
        /// </param>
        /// <param name="tags">
        /// The tags.
        /// </param>
        /// <returns>
        /// A <see cref="string"/> value.
        /// </returns>
        private static string BuildSupportedTagsMessage(IXPathNavigable node, IEnumerable <SupportedTagAttribute> tags)
        {
            var supportedTags = tags.Select(x => x.ToString()).Aggregate((i, j) => i + Environment.NewLine + j);

            var navigator = node.GetNavigator();

            var message = string.Format(
                CultureInfo.CurrentCulture,
                "The specified '{0}' element is invalid. The supported tags for this node are: {1}",
                navigator.Name,
                supportedTags);

            return(message);
        }
        /// <summary>
        /// Sets the selected.
        /// </summary>
        /// <param name="navigable">
        /// The navigable.
        /// </param>
        /// <param name="value">
        /// if set to <c>true</c> [value].
        /// </param>
        public static void SetSelected(this IXPathNavigable navigable, bool value)
        {
            var navigator = navigable.GetNavigator();

            var hasAttribute = navigator.MoveToAttribute("selected", string.Empty);

            if (hasAttribute == value)
            {
                // No change is required
                return;
            }

            if (value)
            {
                // Set the attribute
                navigator.SetAttribute(string.Empty, "selected", string.Empty, "selected");
            }
            else
            {
                // Remove the checked attribute if it exists
                navigator.DeleteSelf();
            }
        }
        public static Type FindBestMatchingType(this Type elementType, IXPathNavigable node)
        {
            if (elementType == null)
            {
                throw new ArgumentNullException("elementType");
            }

            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            var navigator = node.GetNavigator();
            var possibleTypes = GetMatchingTypes(elementType).ToList();
            var matchingTypes = new List<Type>();

            // The node name should already be folded to lower case when the HTML was read
            var nodeName = navigator.Name;

            foreach (var possibleType in possibleTypes)
            {
                var attributes =
                    possibleType.GetCustomAttributes(typeof(SupportedTagAttribute), true)
                        .OfType<SupportedTagAttribute>();

                foreach (var attribute in attributes)
                {
                    if (nodeName.Equals(attribute.TagName, StringComparison.OrdinalIgnoreCase) == false)
                    {
                        continue;
                    }

                    if (attribute.HasAttributeFilter)
                    {
                        // The attribute name should already be folded to lower case when the HTML was read
                        var queryAttributeName = attribute.AttributeName.ToLowerInvariant();

                        var matchingAttribute = navigator.GetAttribute(queryAttributeName, string.Empty);

                        if (matchingAttribute.Equals(attribute.AttributeValue, StringComparison.OrdinalIgnoreCase))
                        {
                            matchingTypes.Add(possibleType);
                        }
                    }
                    else
                    {
                        matchingTypes.Add(possibleType);
                    }
                }
            }

            if (matchingTypes.Count == 0)
            {
                return typeof(AnyHtmlElement);
            }

            if (matchingTypes.Count > 1)
            {
                var matchingTypeNames = matchingTypes.Aggregate(string.Empty, (x, y) => x + Environment.NewLine + y);
                var message = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.TypeExtensions_MultipleTypeMatchesForNode,
                    elementType.FullName,
                    navigator.OuterXml,
                    matchingTypeNames);

                throw new InvalidHtmlElementMatchException(message);
            }

            return matchingTypes[0];
        }
Beispiel #6
0
        public static Type FindBestMatchingType(this Type elementType, IXPathNavigable node)
        {
            if (elementType == null)
            {
                throw new ArgumentNullException("elementType");
            }

            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            var navigator     = node.GetNavigator();
            var possibleTypes = GetMatchingTypes(elementType).ToList();
            var matchingTypes = new List <Type>();

            // The node name should already be folded to lower case when the HTML was read
            var nodeName = navigator.Name;

            foreach (var possibleType in possibleTypes)
            {
                var attributes =
                    possibleType.GetCustomAttributes(typeof(SupportedTagAttribute), true)
                    .OfType <SupportedTagAttribute>();

                foreach (var attribute in attributes)
                {
                    if (nodeName.Equals(attribute.TagName, StringComparison.OrdinalIgnoreCase) == false)
                    {
                        continue;
                    }

                    if (attribute.HasAttributeFilter)
                    {
                        // The attribute name should already be folded to lower case when the HTML was read
                        var queryAttributeName = attribute.AttributeName.ToLowerInvariant();

                        var matchingAttribute = navigator.GetAttribute(queryAttributeName, string.Empty);

                        if (matchingAttribute.Equals(attribute.AttributeValue, StringComparison.OrdinalIgnoreCase))
                        {
                            matchingTypes.Add(possibleType);
                        }
                    }
                    else
                    {
                        matchingTypes.Add(possibleType);
                    }
                }
            }

            if (matchingTypes.Count == 0)
            {
                return(typeof(AnyHtmlElement));
            }

            if (matchingTypes.Count > 1)
            {
                var matchingTypeNames = matchingTypes.Aggregate(string.Empty, (x, y) => x + Environment.NewLine + y);
                var message           = string.Format(
                    CultureInfo.CurrentCulture,
                    Resources.TypeExtensions_MultipleTypeMatchesForNode,
                    elementType.FullName,
                    navigator.OuterXml,
                    matchingTypeNames);

                throw new InvalidHtmlElementMatchException(message);
            }

            return(matchingTypes[0]);
        }
        /// <summary>
        /// Builds the supported tags message.
        /// </summary>
        /// <param name="node">
        /// The node.
        /// </param>
        /// <param name="tags">
        /// The tags.
        /// </param>
        /// <returns>
        /// A <see cref="string"/> value.
        /// </returns>
        private static string BuildSupportedTagsMessage(IXPathNavigable node, IEnumerable<SupportedTagAttribute> tags)
        {
            var supportedTags = tags.Select(x => x.ToString()).Aggregate((i, j) => i + Environment.NewLine + j);

            var navigator = node.GetNavigator();

            var message = string.Format(
                CultureInfo.CurrentCulture,
                "The specified '{0}' element is invalid. The supported tags for this node are: {1}",
                navigator.Name,
                supportedTags);

            return message;
        }