示例#1
0
        internal static bool IsMatch(this HtmlAgilityPack.HtmlNode node, IEnumerable <SimpleSelector> selectors)
        {
            var stack       = new Stack <SimpleSelector>(selectors);
            var currentRule = stack.Pop();

            if (!node.IsMatch(currentRule, stack))
            {
                return(false);
            }

            //no more selectors, its a match
            if (!stack.Any())
            {
                return(true);
            }

            var currentNode = node.ParentNode;

            currentRule = stack.Pop();

            while (currentNode != null)
            {
                if (currentNode.IsMatch(currentRule, stack))
                {
                    if (stack.Any())
                    {
                        currentRule = stack.Pop();
                    }
                    else
                    {
                        //no more rules left to match ad we still have ode context then return true
                        return(true);
                    }
                }

                //keep moving up the dom
                currentNode = currentNode.ParentNode;
            }
            //We must still have unmatched css selectors

            return(false);
        }
示例#2
0
        internal static bool IsMatch(this HtmlAgilityPack.HtmlNode node, SimpleSelector selector, Stack <SimpleSelector> remainingStack)
        {
            if (!string.IsNullOrEmpty(selector.ElementName) && node.Name != selector.ElementName)
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(selector.ID) && node.Id != selector.ID)
            {
                return(false);
            }

            if (!string.IsNullOrEmpty(selector.Class))
            {
                var classString = node.Attributes.Contains("class") ? node.Attributes["class"].Value : "";
                if (!classString.Split(' ').Contains(selector.Class))
                {
                    return(false);
                }
            }
            if (!string.IsNullOrEmpty(selector.Pseudo))
            {
                if (!node.IsPseudoMatch(selector, remainingStack))
                {
                    return(false);
                }
            }


            if (selector.Combinator != null && remainingStack.Any())
            {
                var nextSel = remainingStack.Pop();

                switch (selector.Combinator.Value)
                {
                case Combinator.ChildOf:

                    if (node.ParentNode == null)                            //has to be a child of something
                    {
                        return(false);
                    }
                    if (!node.ParentNode.IsMatch(nextSel, remainingStack))
                    {
                        return(false);
                    }
                    break;

                case Combinator.Namespace:
                    //we are not going to support this until I see a valid use case
                    return(false);

                case Combinator.PrecededBy:

                    if (!node.PreviousSiblingsNotText().Any(x => x.IsMatch(nextSel, remainingStack)))
                    {
                        return(false);
                    }

                    break;

                case Combinator.PrecededImmediatelyBy:
                    var sib = node.PreviousSiblingNotText();
                    if (sib == null)                            //has to be a child of something
                    {
                        return(false);
                    }
                    if (!sib.IsMatch(nextSel, remainingStack))
                    {
                        return(false);
                    }

                    break;

                default:
                    break;
                }
            }
            if (selector.Attribute != null)
            {
                if (!node.IsMatch(selector.Attribute))
                {
                    return(false);
                }
            }
            if (selector.Child != null)
            {
                return(node.IsMatch(selector.Child, remainingStack));
            }

            return(true);
        }
示例#3
0
 internal static IEnumerable <Selector> Matches(this HtmlAgilityPack.HtmlNode node, IEnumerable <Selector> selectors)
 {
     return(selectors.Where(x => node.IsMatch(x.SimpleSelectors)));
 }