Beispiel #1
0
        /// <summary>
        /// 创建带范畴限定的选择器
        /// </summary>
        /// <param name="expression">选择器表达式</param>
        /// <param name="scope">范畴限定,上溯时不超出此范畴</param>
        /// <returns>带范畴限定的层叠选择器</returns>
        public static ISelector Create(IHtmlContainer scope, string expression)
        {
            if (scope == null)
            {
                throw new ArgumentNullException("scope");
            }

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

            return(CssCasecadingSelector.Create(new CssAncetorRelativeSelector(new ContainerRestrict(scope)), CssParser.ParseSelector(expression)));
        }
        /// <summary>
        /// 合并两个关系选择器
        /// </summary>
        /// <param name="left">左关系选择器</param>
        /// <param name="right">右关系选择器</param>
        /// <returns>合并后的关系选择器</returns>
        public static CssRelativeSelector Combine(CssRelativeSelector left, CssRelativeSelector right)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }

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


            var selector   = right.LeftSelector;
            var combinator = right.Combinator;


            var casecadingSelector = selector as CssCasecadingSelector;

            if (casecadingSelector != null)                                                                          //如果右边关系选择器的左选择器是一个层叠选择器
            {
                return(CreateRelativeSelector(CssCasecadingSelector.Combine(left, casecadingSelector), combinator)); //将层叠选择器与左边的关系选择器合并,得到一个新的层叠选择器,再根据结合符创建新的关系选择器。
            }

            /*
             * 举例说明如下:
             * 假设左关系选择器是 p>,右关系选择器是 div>ul>li+
             * 则右关系选择器的左选择器(selector)是div>ul>li,结合符(combinator)是+。
             * 将selector与左边的关系选择器合并,得到:p>div>ul>li,再与结合符结合得到新的关系选择器:p>div>ul>li+
             */

            var elementSelector = selector as CssElementSelector;

            if (elementSelector != null)
            {
                return(CreateRelativeSelector(new CssCasecadingSelector(left, elementSelector), combinator));
            }


            throw new NotSupportedException();
        }
        /// <summary>
        /// 在元素集所有子代元素中使用 CSS 选择器选出符合要求的元素
        /// </summary>
        /// <param name="elements">作为选择范围的元素集</param>
        /// <param name="expression">CSS 选择器表达式</param>
        /// <returns>符合选择器的所有子代</returns>
        public static IEnumerable <IHtmlElement> Find(this IEnumerable <IHtmlElement> elements, string expression)
        {
            if (!elements.Any())
            {
                return(Enumerable.Empty <IHtmlElement>());
            }

            if (elements.IsSingle())
            {
                return(elements.Single().Find(expression));
            }

            var document = elements.First().Document;

            if (elements.Any(e => !e.Document.Equals(document)))
            {
                throw new InvalidOperationException("不支持在不同的文档中搜索");
            }

            var selector = CssCasecadingSelector.Create(elements, expression);

            return(selector.Filter(document.Descendants()));
        }
 /// <summary>
 /// 合并关系选择器和层叠选择器
 /// </summary>
 /// <param name="relativeSelector">关系选择器</param>
 /// <param name="selector">层叠选择器</param>
 /// <returns></returns>
 internal static CssCasecadingSelector Combine(CssRelativeSelector relativeSelector, CssCasecadingSelector selector)
 {
     relativeSelector = Combine(relativeSelector, selector.RelativeSelector);
     return(new CssCasecadingSelector(relativeSelector, selector.LastSelector));
 }
Beispiel #5
0
 /// <summary>
 /// 创建层叠选择器
 /// </summary>
 /// <param name="leftSelector">左选择器</param>
 /// <param name="combanitor">结合符</param>
 /// <param name="rightSelector">右选择器</param>
 /// <returns>层叠选择器</returns>
 private static ISelector CreateCasecadingSelector(ISelector leftSelector, char combanitor, CssElementSelector rightSelector)
 {
     return(CssCasecadingSelector.Create(leftSelector, combanitor, rightSelector));
 }
 public static ISelector Combine(CssRelativeSelector relativeSelector, CssMultipleSelector multipleSelector)
 {
     return(new CssMultipleSelector(multipleSelector._selectors.Select(selector => CssCasecadingSelector.Create(relativeSelector, selector)).ToArray()));
 }
 /// <summary>
 /// 合并关系选择器和层叠选择器
 /// </summary>
 /// <param name="relativeSelector">关系选择器</param>
 /// <param name="selector">层叠选择器</param>
 /// <returns></returns>
 internal static CssCasecadingSelector Combine( CssRelativeSelector relativeSelector, CssCasecadingSelector selector )
 {
     relativeSelector = Combine( relativeSelector, selector.RelativeSelector );
       return new CssCasecadingSelector( relativeSelector, selector.LastSelector );
 }