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); }
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; }
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); }