Esempio n. 1
0
        public static IList <HtmlNode> QuerySelectorAll(this IEnumerable <HtmlNode> nodes, string cssSelector)
        {
            if (cssSelector == null)
            {
                throw new ArgumentNullException(nameof(cssSelector));
            }

            if (cssSelector.Contains(','))
            {
                var combinedSelectors = cssSelector.Split(',');
                var rt = nodes.QuerySelectorAll(combinedSelectors[0]);
                foreach (var s in combinedSelectors.Skip(1))
                {
                    foreach (var n in nodes.QuerySelectorAll(s))
                    {
                        if (!rt.Contains(n))
                        {
                            rt.Add(n);
                        }
                    }
                }

                return(rt);
            }

            cssSelector = cssSelector.Trim();

            var selectors = CssSelector.Parse(cssSelector);

            bool allowTraverse = true;

            for (int i = 0; i < selectors.Count; i++)
            {
                var selector = selectors[i];

                if (allowTraverse && selector.AllowTraverse)
                {
                    // If this is not the first selector then we must make filter against the child nodes of the current set of nodes
                    // since any selector that follows another selector always scopes down the nodes to the descendants of the last scope.
                    // Example: "span span" Should only resolve with span elements that are descendants of another span element.
                    // Any span elements that are not descendant of another span element shoud not be included in the output.
                    if (i > 0)
                    {
                        nodes = nodes.SelectMany(n => n.ChildNodes);
                    }

                    nodes = Traverse(nodes);
                }

                nodes         = selector.Filter(nodes);
                allowTraverse = selector.AllowTraverse;
            }

            return(nodes.Distinct().ToList());
        }
Esempio n. 2
0
        public static IList <HtmlNode> QuerySelectorAll(this IEnumerable <HtmlNode> nodes, string cssSelector)
        {
            if (cssSelector == null)
            {
                throw new ArgumentNullException(nameof(cssSelector));
            }

            if (cssSelector.Contains(','))
            {
                var combinedSelectors = cssSelector.Split(',');
                var rt = nodes.QuerySelectorAll(combinedSelectors[0]);
                foreach (var s in combinedSelectors.Skip(1))
                {
                    foreach (var n in nodes.QuerySelectorAll(s))
                    {
                        if (!rt.Contains(n))
                        {
                            rt.Add(n);
                        }
                    }
                }

                return(rt);
            }

            cssSelector = cssSelector.Trim();

            var selectors = CssSelector.Parse(cssSelector);

            bool allowTraverse = true;

            foreach (var selector in selectors)
            {
                if (allowTraverse && selector.AllowTraverse)
                {
                    nodes = Traverse(nodes);
                }

                nodes         = selector.Filter(nodes);
                allowTraverse = selector.AllowTraverse;
            }

            return(nodes.Distinct().ToList());
        }