Beispiel #1
0
 /// <summary>
 /// Create a new comment from another.
 /// </summary>
 public HComment(HComment other)
 {
     if (other == null)
     {
         throw new ArgumentNullException("other");
     }
     this.value = other.value;
 }
Beispiel #2
0
        /// <summary>
        /// Deserialize as a list of nodes
        /// </summary>
        public IEnumerable <HNode> Deserialize(TextReader reader, Func <Exception, bool> errorHandler = null)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            // Create the parser
            var parser = new HParser(reader);

            parser.RemoveUnknownOrInvalidEntities = this.RemoveUnknownOrInvalidEntities;
            var token = ParseNext(parser, errorHandler);
            Stack <HElement> opened       = new Stack <HElement>();
            HXmlDeclaration  currentXDecl = null;
            String           tag;
            HNode            tokenToReturns = null;

            while (token != null)
            {
                switch (token.TokenType)
                {
                case ParsedTokenType.Text:
                    var htxt = new HText(HEntity.HtmlDecode(((ParsedText)token).Text, RemoveUnknownOrInvalidEntities));
                    if (opened.Count > 0)
                    {
                        ProtectAddOnPeek(opened, htxt, errorHandler);
                    }
                    else
                    {
                        tokenToReturns = htxt;
                    }
                    break;

                case ParsedTokenType.CData:
                    var hcd = new HCData(((ParsedCData)token).Text);
                    if (opened.Count > 0)
                    {
                        ProtectAddOnPeek(opened, hcd, errorHandler);
                    }
                    else
                    {
                        tokenToReturns = hcd;
                    }
                    break;

                case ParsedTokenType.Comment:
                    var hcom = new HComment(HEntity.HtmlDecode(((ParsedComment)token).Text, RemoveUnknownOrInvalidEntities));
                    if (opened.Count > 0)
                    {
                        ProtectAddOnPeek(opened, hcom, errorHandler);
                    }
                    else
                    {
                        tokenToReturns = hcom;
                    }
                    break;

                case ParsedTokenType.OpenTag:
                    opened.Push(new HElement(((ParsedTag)token).TagName));
                    break;

                case ParsedTokenType.AutoClosedTag:
                    System.Diagnostics.Debug.Assert(opened.Count > 0, "Opened tags are empty when receiving AutoClosedTag.");
                    System.Diagnostics.Debug.Assert(opened.Peek().Name == ((ParsedTag)token).TagName, "AutoClosedTag and opened element are not same tag name.");
                    var actag = opened.Pop();
                    if (opened.Count > 0)
                    {
                        ProtectAddOnPeek(opened, actag, errorHandler);
                    }
                    else
                    {
                        tokenToReturns = actag;
                    }
                    break;

                case ParsedTokenType.CloseTag:
                    System.Diagnostics.Debug.Assert(opened.Count > 0, "Opened tags are empty when receiving CloseTag.");
                    System.Diagnostics.Debug.Assert(opened.Peek().Name == ((ParsedTag)token).TagName, "CloseTag and opened element are not same tag name.");
                    // Tag with text content
                    String tagName = opened.Peek().Name;
                    if (IsRawElement(tagName) || IsEscapableRawElement(tagName))
                    {
                        token = ParseContentTextNext(tagName, parser, errorHandler);
                        continue;
                    }
                    break;

                case ParsedTokenType.EndTag:
                    tag = ((ParsedTag)token).TagName;
                    HElement helm;
                    // Close all elements that not matching the tag
                    while (opened.Count > 0 && !String.Equals(opened.Peek().Name, tag, StringComparison.OrdinalIgnoreCase))
                    {
                        helm = opened.Pop();
                        if (opened.Count > 0)
                        {
                            ProtectAddOnPeek(opened, helm, errorHandler);
                        }
                        else
                        {
                            yield return(helm);
                        }
                    }
                    // If we are opened tag, then close it because we find our element
                    if (opened.Count > 0)
                    {
                        helm = opened.Pop();
                        if (opened.Count > 0)
                        {
                            ProtectAddOnPeek(opened, helm, errorHandler);
                        }
                        else
                        {
                            yield return(helm);
                        }
                    }
                    break;

                case ParsedTokenType.OpenProcessInstruction:
                    if (currentXDecl != null)
                    {
                        while ((token = ParseNext(parser, errorHandler)) != null && token.TokenType != ParsedTokenType.CloseProcessInstruction)
                        {
                            ;
                        }
                        ProcessError(new ParseError("XML declaration already opened."), errorHandler);
                    }
                    tag = ((ParsedTag)token).TagName;
                    if (!String.Equals("xml", tag, StringComparison.OrdinalIgnoreCase))
                    {
                        while ((token = ParseNext(parser, errorHandler)) != null && token.TokenType != ParsedTokenType.CloseProcessInstruction)
                        {
                            ;
                        }
                        ProcessError(new ParseError(String.Format("Unexpected '{0}' process instruction.", tag)), errorHandler);
                    }
                    currentXDecl = new HXmlDeclaration(null, null, null);
                    break;

                case ParsedTokenType.CloseProcessInstruction:
                    if (currentXDecl == null)
                    {
                        ProcessError(new ParseError("No XML declaration opened."), errorHandler);
                    }
                    else
                    {
                        if (opened.Count > 0)
                        {
                            ProtectAddOnPeek(opened, currentXDecl, errorHandler);
                        }
                        else
                        {
                            tokenToReturns = currentXDecl;
                        }
                    }
                    currentXDecl = null;
                    break;

                case ParsedTokenType.Doctype:
                    var vs  = ((ParsedDoctype)token).Values ?? new String[0];
                    var hdt = new HDocumentType(
                        vs.Length > 0 ? vs[0] : null,
                        vs.Length > 1 ? vs[1] : null,
                        vs.Length > 2 ? vs[2] : null,
                        vs.Length > 3 ? vs[3] : null
                        );
                    if (opened.Count > 0)
                    {
                        ProtectAddOnPeek(opened, hdt, errorHandler);
                    }
                    else
                    {
                        tokenToReturns = hdt;
                    }
                    break;

                case ParsedTokenType.Attribute:
                    var attr = (ParsedAttribute)token;
                    // Xml declaration ?
                    if (currentXDecl != null)
                    {
                        if (String.Equals("version", attr.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            currentXDecl.Version = attr.Value;
                        }
                        else if (String.Equals("encoding", attr.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            currentXDecl.Encoding = attr.Value;
                        }
                        else if (String.Equals("standalone", attr.Name, StringComparison.OrdinalIgnoreCase))
                        {
                            currentXDecl.Standalone = attr.Value;
                        }
                        else
                        {
                            ProcessError(new ParseError(String.Format("Invalid XML declaration attribute : ''", attr.Name)), errorHandler);
                        }
                    }
                    System.Diagnostics.Debug.Assert(opened.Count > 0, "No element opened for the attribtue.");
                    ProtectAddOnPeek(opened, new HAttribute(attr.Name, attr.Value), errorHandler);
                    break;
                    //default:
                    //    break;
                }
                // Returns a token if we have one
                if (tokenToReturns != null)
                {
                    yield return(tokenToReturns);

                    tokenToReturns = null;
                }
                // Next token
                token = ParseNext(parser, errorHandler);
            }
            // Close all opened elements
            while (opened.Count > 0)
            {
                yield return(opened.Pop());
            }
        }
Beispiel #3
0
 /// <summary>
 /// Serialize a comment
 /// </summary>
 protected virtual void SerializeComment(HComment comment, TextWriter writer)
 {
     writer.Write("<!-- ");
     writer.Write(HEntity.HtmlEncode(comment.Value));
     writer.Write(" -->");
 }