/// <summary> /// Finds the first match for the type, and must match the attributes if they're specified. Option to disable recursive search will only search on the next level if set to false. /// </summary> /// <param name="type"></param> /// <param name="attributes"></param> /// <returns></returns> public HtmlItem Get(string type, Dictionary <string, string> attributes = null, bool continueUp = false, bool recursive = true) { //look through children HtmlItem i; if ((i = get(type, attributes, recursive)) != null) { return(i); } //if we can continue up if (continueUp) { HtmlItem n = next(); if (n != null) { //first check if it matches if (n.IsType(type) && n.HasAttributes(attributes)) { return(n); } return(n.Get(type, attributes, continueUp, recursive)); } } return(null); }
public bool Matches(HtmlItem item) { //if it's the right type if (item.IsType(Type)) { //check if there's the right number of attributes if (AttributesCount != -1 && item.Attributes.Count != AttributesCount) { return(false); } //if we have to check the properties if (Attributes != null) { //if any property fails to match, the whole thing doesn't match for (int i = 0; i < Attributes.Length; i++) { if (!Attributes[i].Matches(item)) { return(false); } } } return(true); } return(false); }
public LinkedList <HtmlItem> GetRange(string type, Dictionary <string, string> attributes) { HtmlItem stop = Next(false); HtmlItem item = this; LinkedList <HtmlItem> list = new LinkedList <HtmlItem>(); while ((item = item.Next()) != stop) { if (item.IsType(type) && item.HasAttributes(attributes)) { list.AddLast(item); } } return(list); }
private bool parseInner(string data, HtmlItem parent, HtmlItem item) { while (i + 1 < data.Length) { //trim any leading space trimSpace(data); //if there's an inner tag if (isStart(data)) { //read inner tags parse(data, item); if (i + 1 < data.Length && isEnd(data, 1)) { //if (!StringTools.Grab(data, i, "</~>", 1)[0].Equals(item.Type)) if (!item.IsType(StringTools.Grab(data, i, "</~>", 1)[0])) { return(true); } break; } } //otherwise it just had a value else { //find end tag for (int x = i; x < data.Length; x++) { if (isEnd(data, x)) { item.Value = data.Substring(i, x - i); i = x; break; } } //if (!StringTools.Grab(data, i, "</~>", 1)[0].Equals(item.Type)) if (!item.IsType(StringTools.Grab(data, i, "</~>", 1)[0])) { return(true); } break; } } //now advance past the end tag for (; i < data.Length; i++) { if (isClose(data, i)) { i++; break; } } return(false); }
private string parse(string data, HtmlItem parent) { string value = null; while (i < data.Length) { //if at opening tag if (isStart(data)) { //create item HtmlItem item = createItem(data, parent); //if it's a list item, and the parent is also a list item if (item.IsType("li") && parent.IsType("li")) { //add to parent's parent parent.Parent.Children.Add(item); //reassign the parent item.Parent = parent.Parent; //scan next stuff item.Value = parse(data, item); //return the value to exit this inner return(value); } //add to parent parent.Children.Add(item); //if it's not self closing and it's not a break tag if (data[i - 2] != '/' && !item.IsType("br") && !item.IsType("img")) { //set item value to inner data item.Value = parse(data, item); } } //else if at closing tag else if (isEnd(data, i)) { int x; //if tag type matches parent if ((x = StringTools.Grab(data, i, "</~>", arr)) != -1) { //if it was a </br> tag if (arr[0].Equals("br", StringComparison.CurrentCultureIgnoreCase)) { //add the break to the parent parent.Children.Add(new HtmlItem() { Type = arr[0], Attributes = new Dictionary <string, string>(), Children = new List <HtmlItem>(), Parent = parent }); //advance past close i = x; continue; } //if tag type matches parent //else if (arr[0].Equals(parent.Type)) else if (parent.IsType(arr[0])) { //advance past close i = x; } } //return the value return(value); } else if (i + 1 < data.Length && data[i] == '<' && data[i + 1] == '!') { //move forward past the '>' for (; i < data.Length && data[i] != '>'; i++) { ; } i++; } //else we just have the value else { StringBuilder builder = new StringBuilder(); //move forward until '<' bool firstWhitespace = true; for (; i < data.Length && data[i] != '<'; i++) { //only include one whitespace character (removes multiple consecutive spaces) like proper HTML if (char.IsWhiteSpace(data[i])) { if (firstWhitespace) { firstWhitespace = false; builder.Append(' '); } } else { firstWhitespace = true; builder.Append(data[i]); } } //temp = temp.Trim(); parent.Children.Add(new HtmlItem() { Type = "Text", Value = builder.ToString(), Attributes = new Dictionary <string, string>(), Children = new List <HtmlItem>(), Parent = parent }); } } return(value); }