public override HtmlXPathTemplate Read() { HtmlXPathTemplate template = new HtmlXPathTemplate(); string[] lines = new SplitText( RawTemplate, StringSplitOptions.RemoveEmptyEntries, Options.LineEnding); template.RootNodeXPath = lines[0]; List <HtmlXPathTemplatePattern> list = new List <HtmlXPathTemplatePattern>(); HtmlXPathTemplatePattern lastPattern = null; for (int i = 1; i < lines.Length; i++) { string line = lines[i]; HtmlXPathTemplatePattern pattern = new HtmlXPathTemplatePattern(); { pattern.Level = line .SplitByLength(Options.Tabulator.Length) .TakeWhile(x => x == Options.Tabulator) .Count(); } { Regex innerTextRegex = new Regex(@"\/\$(?<innerText>\w+)$"); Match innerTextMatch = innerTextRegex.Match(line); if (innerTextMatch.Success) { pattern.InnerTextVariable = innerTextMatch.Groups["innerText"].Value; line = line.Substring(0, line.Length - pattern.InnerTextVariable.Length - 2); } } { Regex attributeRegex = new Regex(@"@(?<from>[^=]+)=\$(?<to>\w+)"); MatchCollection attributeMatches = attributeRegex.Matches(line); foreach (Match attributeMatch in attributeMatches) { if (attributeMatch.Success) { pattern.AddAttributeVariable( attributeMatch.Groups["from"].Value, attributeMatch.Groups["to"].Value); line = attributeRegex.Replace(line, m => $"@{m.Groups["from"].Value}", 1); } } } { pattern.XPathSelector = line.Substring(Options.Tabulator.Length * pattern.Level); } if (pattern.Level == 1) { list.Add(pattern); } else { bool found = false; HtmlXPathTemplatePattern potentialParent = lastPattern; while (potentialParent != null) { if (potentialParent.Level == pattern.Level - 1) { found = true; pattern.Parent = potentialParent; potentialParent.AddChild(pattern); break; } potentialParent = potentialParent.Parent; } if (!found) { throw new InvalidDataException( $"Parent could not be found for the pattern with index={i}. Expected parent level is {pattern.Level - 1}. XPathSelector={pattern.XPathSelector}"); } } lastPattern = pattern; } template.Patterns = list.ToArray(); return(template); }
public void AddChild(HtmlXPathTemplatePattern pattern) => _children.Add(pattern);