private string PseudoClassesToXPath(Match match, XPathNavigator nav)
        {
            int    specificityA = 0;
            int    specificityB = 1;
            int    specificityC = 0;
            string r            = string.Empty;
            Group  g            = match.Groups["pseudoclass"];

            foreach (Capture c in g.Captures)
            {
                string p = c.Value.Substring(1);

                if (p == "root")
                {
                    r += "[not(parent::*)]";
                }
                else if (p.StartsWith("not", StringComparison.OrdinalIgnoreCase))
                {
                    string           expr = p.Substring(4, p.Length - 5);
                    CssXPathSelector sel  = new CssXPathSelector(expr, _nsTable);

                    string xpath = sel.XPath;
                    if (xpath != null && xpath.Length > 3)
                    {
                        // remove *[ and ending ]
                        xpath = xpath.Substring(2, xpath.Length - 3);

                        r += "[not(" + xpath + ")]";

                        int specificity = sel.Specificity;

                        // specificity = 123
                        specificityA = (int)Math.Floor((double)specificity / 100);
                        specificity -= specificityA * 100;
                        // specificity = 23
                        specificityB = (int)Math.Floor((double)(specificity) / 10);

                        specificity -= specificityB * 10;
                        // specificity = 3
                        specificityC = specificity;
                    }
                }
                else if (p == "first-child")
                {
                    r += "[count(preceding-sibling::*)=0]";
                }
                else if (p == "last-child")
                {
                    r += "[count(following-sibling::*)=0]";
                }
                else if (p == "only-child")
                {
                    r += "[count(../*)=1]";
                }
                else if (p == "only-of-type")
                {
                    r += "[false]";
                }
                else if (p == "empty")
                {
                    r += "[not(child::*) and not(text())]";
                }
                else if (p == "target")
                {
                    r += "[false]";
                }
                else if (p == "first-of-type")
                {
                    r += "[false]";
                    //r += "[.=(../*[local-name='roffe'][position()=1])]";
                }
                else if (_reLang.IsMatch(p))
                {
                    r += "[lang('" + _reLang.Match(p).Groups[1].Value + "')]";
                }
                else if (_reContains.IsMatch(p))
                {
                    r += "[contains(string(.),'" + _reContains.Match(p).Groups["stringvalue"].Value + "')]";
                }
                else if (_reNth.IsMatch(p))
                {
                    Match  m    = _reNth.Match(p);
                    string type = m.Groups["type"].Value;
                    string exp  = m.Groups["exp"].Value;
                    int    a    = 0;
                    int    b    = 0;
                    if (exp == "odd")
                    {
                        a = 2;
                        b = 1;
                    }
                    else if (exp == "even")
                    {
                        a = 2;
                        b = 0;
                    }
                    else
                    {
                        string v = m.Groups["a"].Value;

                        if (v.Length == 0)
                        {
                            a = 1;
                        }
                        else if (v.Equals("-"))
                        {
                            a = -1;
                        }
                        else
                        {
                            a = int.Parse(v);
                        }

                        if (m.Groups["b"].Success)
                        {
                            b = int.Parse(m.Groups["b"].Value);
                        }
                    }


                    if (type.Equals("nth-child", StringComparison.OrdinalIgnoreCase) ||
                        type.Equals("nth-last-child", StringComparison.OrdinalIgnoreCase))
                    {
                        string axis;
                        if (type.Equals("nth-child", StringComparison.OrdinalIgnoreCase))
                        {
                            axis = "preceding-sibling";
                        }
                        else
                        {
                            axis = "following-sibling";
                        }

                        if (a == 0)
                        {
                            r += "[count(" + axis + "::*)+1=" + b + "]";
                        }
                        else
                        {
                            r += "[((count(" + axis + "::*)+1-" + b + ") mod " + a + "=0)and((count(" + axis + "::*)+1-" + b + ") div " + a + ">=0)]";
                        }
                    }
                }
                AddSpecificity(specificityA, specificityB, specificityC);
            }
            return(r);
        }
Example #2
0
        private string PseudoClassesToXPath(Match match, XPathNavigator nav)
        {
            int specificityA = 0;
            int specificityB = 1;
            int specificityC = 0;
            string r = String.Empty;
            Group g = match.Groups["pseudoclass"];

            foreach(Capture c in g.Captures)
            {
                Regex reLang = new Regex(@"^lang\(([A-Za-z\-]+)\)$");
                Regex reContains = new Regex("^contains\\((\"|\')?(?<stringvalue>.*?)(\"|\')?\\)$");

                string s = @"^(?<type>(nth-child)|(nth-last-child)|(nth-of-type)|(nth-last-of-type))\(\s*";
                s += @"(?<exp>(odd)|(even)|(((?<a>[\+-]?\d*)n)?(?<b>[\+-]?\d+)?))";
                s += @"\s*\)$";
                Regex reNth = new Regex(s);

                string p = c.Value.Substring(1);

                if(p == "root")
                {
                    r += "[not(parent::*)]";
                }
                else if(p.StartsWith("not"))
                {
                    string expr = p.Substring(4, p.Length-5);
                    CssXPathSelector sel = new CssXPathSelector(expr, _nsTable);

                    string xpath = sel.XPath;
                    if(xpath != null && xpath.Length>3)
                    {
                        // remove *[ and ending ]
                        xpath = xpath.Substring(2, xpath.Length-3);

                        r += "[not(" + xpath + ")]";

                        int specificity = sel.Specificity;

                        // specificity = 123
                        specificityA = (int)Math.Floor((double) specificity / 100);
                        specificity -= specificityA*100;
                        // specificity = 23
                        specificityB = (int)Math.Floor((double) (specificity) / 10);

                        specificity -= specificityB * 10;
                        // specificity = 3
                        specificityC = specificity;
                    }
                }
                else if(p == "first-child")
                {
                    r += "[count(preceding-sibling::*)=0]";
                }
                else if(p == "last-child")
                {
                    r += "[count(following-sibling::*)=0]";
                }
                else if(p == "only-child")
                {
                    r += "[count(../*)=1]";
                }
                else if(p == "only-of-type")
                {
                    r += "[false]";
                }
                else if(p == "empty")
                {
                    r += "[not(child::*) and not(text())]";
                }
                else if(p == "target")
                {
                    r += "[false]";
                }
                else if(p == "first-of-type")
                {
                    r += "[false]";
                    //r += "[.=(../*[local-name='roffe'][position()=1])]";
                }
                else if(reLang.IsMatch(p))
                {
                    r += "[lang('" + reLang.Match(p).Groups[1].Value + "')]";
                }
                else if(reContains.IsMatch(p))
                {
                    r += "[contains(string(.),'" + reContains.Match(p).Groups["stringvalue"].Value + "')]";
                }
                else if(reNth.IsMatch(p))
                {
                    Match m = reNth.Match(p);
                    string type = m.Groups["type"].Value;
                    string exp = m.Groups["exp"].Value;
                    int a = 0;
                    int b = 0;
                    if(exp == "odd")
                    {
                        a = 2;
                        b = 1;
                    }
                    else if(exp == "even")
                    {
                        a = 2;
                        b = 0;
                    }
                    else
                    {
                        string v = m.Groups["a"].Value;

                        if(v.Length == 0) a = 1;
                        else if(v.Equals("-")) a = -1;
                        else a = Int32.Parse(v);

                        if(m.Groups["b"].Success) b = Int32.Parse(m.Groups["b"].Value);
                    }

                    if(type.Equals("nth-child") || type.Equals("nth-last-child"))
                    {
                        string axis;
                        if(type.Equals("nth-child")) axis = "preceding-sibling";
                        else axis = "following-sibling";

                        if(a == 0)
                        {
                            r += "[count(" + axis + "::*)+1=" + b + "]";
                        }
                        else
                        {
                            r += "[((count(" + axis + "::*)+1-" + b + ") mod " + a + "=0)and((count(" + axis + "::*)+1-" + b + ") div " + a + ">=0)]";
                        }
                    }
                }
                AddSpecificity(specificityA, specificityB, specificityC);
            }
            return r;
        }
Example #3
0
        private string PseudoClassesToXPath(Match match, XPathNavigator nav)
        {
            int    specificityA = 0;
            int    specificityB = 1;
            int    specificityC = 0;
            string r            = String.Empty;
            Group  g            = match.Groups["pseudoclass"];

            foreach (Capture c in g.Captures)
            {
                Regex reLang     = new Regex(@"^lang\(([A-Za-z\-]+)\)$");
                Regex reContains = new Regex("^contains\\((\"|\')?(?<stringvalue>.*?)(\"|\')?\\)$");

                string s = @"^(?<type>(nth-child)|(nth-last-child)|(nth-of-type)|(nth-last-of-type))\(\s*";
                s += @"(?<exp>(odd)|(even)|(((?<a>[\+-]?\d*)n)?(?<b>[\+-]?\d+)?))";
                s += @"\s*\)$";
                Regex reNth = new Regex(s);

                string p = c.Value.Substring(1);

                if (p == "root")
                {
                    r += "[not(parent::*)]";
                }
                else if (p.StartsWith("not"))
                {
                    string           expr = p.Substring(4, p.Length - 5);
                    CssXPathSelector sel  = new CssXPathSelector(expr, _nsTable);

                    string xpath = sel.XPath;
                    if (xpath != null && xpath.Length > 3)
                    {
                        // remove *[ and ending ]
                        xpath = xpath.Substring(2, xpath.Length - 3);

                        r += "[not(" + xpath + ")]";

                        int specificity = sel.Specificity;

                        // specificity = 123
                        specificityA = (int)Math.Floor((double)specificity / 100);
                        specificity -= specificityA * 100;
                        // specificity = 23
                        specificityB = (int)Math.Floor((double)(specificity) / 10);

                        specificity -= specificityB * 10;
                        // specificity = 3
                        specificityC = specificity;
                    }
                }
                else if (p == "first-child")
                {
                    r += "[count(preceding-sibling::*)=0]";
                }
                else if (p == "last-child")
                {
                    r += "[count(following-sibling::*)=0]";
                }
                else if (p == "only-child")
                {
                    r += "[count(../*)=1]";
                }
                else if (p == "only-of-type")
                {
                    r += "[false]";
                }
                else if (p == "empty")
                {
                    r += "[not(child::*) and not(text())]";
                }
                else if (p == "target")
                {
                    r += "[false]";
                }
                else if (p == "first-of-type")
                {
                    r += "[false]";
                    //r += "[.=(../*[local-name='roffe'][position()=1])]";
                }
                else if (reLang.IsMatch(p))
                {
                    r += "[lang('" + reLang.Match(p).Groups[1].Value + "')]";
                }
                else if (reContains.IsMatch(p))
                {
                    r += "[contains(string(.),'" + reContains.Match(p).Groups["stringvalue"].Value + "')]";
                }
                else if (reNth.IsMatch(p))
                {
                    Match  m    = reNth.Match(p);
                    string type = m.Groups["type"].Value;
                    string exp  = m.Groups["exp"].Value;
                    int    a    = 0;
                    int    b    = 0;
                    if (exp == "odd")
                    {
                        a = 2;
                        b = 1;
                    }
                    else if (exp == "even")
                    {
                        a = 2;
                        b = 0;
                    }
                    else
                    {
                        string v = m.Groups["a"].Value;

                        if (v.Length == 0)
                        {
                            a = 1;
                        }
                        else if (v.Equals("-"))
                        {
                            a = -1;
                        }
                        else
                        {
                            a = Int32.Parse(v);
                        }

                        if (m.Groups["b"].Success)
                        {
                            b = Int32.Parse(m.Groups["b"].Value);
                        }
                    }


                    if (type.Equals("nth-child") || type.Equals("nth-last-child"))
                    {
                        string axis;
                        if (type.Equals("nth-child"))
                        {
                            axis = "preceding-sibling";
                        }
                        else
                        {
                            axis = "following-sibling";
                        }

                        if (a == 0)
                        {
                            r += "[count(" + axis + "::*)+1=" + b + "]";
                        }
                        else
                        {
                            r += "[((count(" + axis + "::*)+1-" + b + ") mod " + a + "=0)and((count(" + axis + "::*)+1-" + b + ") div " + a + ">=0)]";
                        }
                    }
                }
                AddSpecificity(specificityA, specificityB, specificityC);
            }
            return(r);
        }