예제 #1
0
        /// <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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }