Exemplo n.º 1
0
        List <HtmlAttribute> GetAttributes(ref bool isSingle)
        {
            List <HtmlAttribute> attributes = new List <HtmlAttribute> ();

            TextTokenizer.MoveNext();
            while (true)
            {
                if (IsEnd(ref isSingle))
                {
                    break;
                }
                switch (TextTokenizer.Current.Type)
                {
                case HtmlTokenType.String:
                    HtmlAttribute attribute = new HtmlAttribute(TextTokenizer.Current);
                    attributes.Add(attribute);
                    TextTokenizer.MoveNext();
                    if (IsEnd(ref isSingle))
                    {
                        return(attributes);
                    }
                    switch (TextTokenizer.Current.Type)
                    {
                    case HtmlTokenType.EqualSign:
                        TextTokenizer.MoveNext();
                        switch (TextTokenizer.Current.Type)
                        {
                        case HtmlTokenType.String:
                            attribute.Values = new List <string> ();
                            string value = HtmlAPI.Unescape(TextTokenizer.Current.String);
                            if (HtmlAPI.Equals(attribute.Name, HtmlKeyword.Class))
                            {
                                attribute.Values.AddRange(HtmlAPI.Split(value));
                            }
                            else
                            {
                                attribute.Values.Add(value);
                            }
                            TextTokenizer.MoveNext();
                            continue;
                        }
                        throw new HtmlTextReaderException <HtmlTokenType> (TextTokenizer, "属性值");

                    case HtmlTokenType.String:
                        continue;

                    default:
                        throw new HtmlTextReaderException <HtmlTokenType> (TextTokenizer, HtmlKeyword.EqualSign, HtmlKeyword.SingleTag, HtmlKeyword.RightAngleBracket);
                    }

                default:
                    throw new HtmlTextReaderException <HtmlTokenType> (TextTokenizer, "属性名", HtmlKeyword.SingleTag, HtmlKeyword.RightAngleBracket);
                }
            }
            return(attributes);
        }
Exemplo n.º 2
0
        bool ReadNode(HtmlElement parentElement, out HtmlNode node, string endElementLocalName = null)
        {
            if (MoveNext())
            {
                switch (Current.Type)
                {
                case HtmlTagType.Define:
                    node = new HtmlDocumentType(Current.Attributes, parentElement);
                    return(true);

                case HtmlTagType.Single:
                    node = new HtmlElement(Current.Name, Current.Attributes, parentElement);
                    return(true);

                case HtmlTagType.Start: {
                    HtmlElement element = new HtmlElement(Current.Name, Current.Attributes, parentElement);
                    node = element;
                    if (HtmlAPI.IsContentTag(element.LocalName))
                    {
                        TextTokenizer.SkipIgnoreCharacters();
                        string text = TextTokenizer.ReadTo($"</{element.LocalName}>").TrimEnd();
                        if (text.Length > 0)
                        {
                            node.ChildNodes.Add(new HtmlText(text, element));
                        }
                        return(true);
                    }
                    Tags.Add(element.LocalName);
                    HtmlNode lastNode = null;
                    while (ReadNode(element, out HtmlNode childNode, element.LocalName))
                    {
                        if (childNode is null)
                        {
                            continue;
                        }
                        if (lastNode != null)
                        {
                            lastNode.NextSibling      = childNode;
                            childNode.PreviousSibling = lastNode;
                        }
                        node.ChildNodes.Add(childNode);
                        lastNode = childNode;
                    }
                    return(true);
                }

                case HtmlTagType.End:
                    if (endElementLocalName != null && !HtmlAPI.Equals(Current.Name, endElementLocalName))
                    {
                        if (Tags.Contains(Current.Name))
                        {
                            Buffer.Push(Current);
                        }
                        else
                        {
                            node = null;
                            return(true);
                        }
                    }
                    if (Tags.Count > 0)
                    {
                        Tags.RemoveAt(Tags.Count - 1);
                    }
                    break;

                case HtmlTagType.Text:
                    node = new HtmlText(HtmlAPI.Unescape(Current.Content), parentElement);
                    return(true);

                case HtmlTagType.Comment:
                    node = new HtmlComment(Current.Content, parentElement);
                    return(true);

                default:
                    throw new NotImplementedException(Current.Type.ToString());
                }
            }
            node = null;
            return(false);
        }