コード例 #1
0
        DtdNotationToken NotationDeclarationAfterSystem(Char c, DtdNotationToken decl)
        {
            var hasError = false;

            while (true)
            {
                if (c == Specification.GT)
                {
                    return decl;
                }
                else if (c == Specification.EOF)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    src.Back();
                    return decl;
                }
                else if (!c.IsSpaceCharacter())
                {
                    if (!hasError)
                        RaiseErrorOccurred(ErrorCode.InputUnexpected);

                    hasError = true;
                }

                c = src.Next;
            }
        }
コード例 #2
0
        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#Notations.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdNotationToken NotationDeclaration(Char c)
        {
            var decl = new DtdNotationToken();
            var canContinue = false;

            if (c.IsSpaceCharacter())
                canContinue = DeclarationNameBefore(src.Next, decl);
            else if (c == Specification.EOF)
                throw new ArgumentException("The document ended unexpectedly.");
            else
            {
                RaiseErrorOccurred(ErrorCode.UndefinedMarkupDeclaration);
                canContinue = DeclarationNameBefore(c, decl);
            }

            if (canContinue)
            {
                if (src.ContinuesWith("PUBLIC", false))
                {
                    src.Advance(5);
                    return NotationDeclarationBeforePublic(src.Next, decl);
                }
                else if (src.ContinuesWith("SYSTEM", false))
                {
                    src.Advance(5);
                    return NotationDeclarationBeforeSystem(src.Next, decl);
                }

                return NotationDeclarationAfterSystem(c, decl);
            }

            RaiseErrorOccurred(ErrorCode.NotationPublicInvalid);
            return decl;
        }
コード例 #3
0
        DtdNotationToken NotationDeclarationAfterPublic(Char c, DtdNotationToken decl)
        {
            while (c.IsSpaceCharacter())
                c = src.Next;

            if (c == Specification.GT)
            {
                return decl;
            }
            else if (c == Specification.EOF)
            {
                RaiseErrorOccurred(ErrorCode.EOF);
                src.Back();
                return decl;
            }
            else if (c == Specification.SQ)
            {
                return NotationDeclarationSystem(src.Next, Specification.SQ, decl);
            }
            else if (c == Specification.DQ)
            {
                return NotationDeclarationSystem(src.Next, Specification.DQ, decl);
            }
            else
            {
                return NotationDeclarationAfterSystem(c, decl);
            }
        }
コード例 #4
0
        DtdNotationToken NotationDeclarationSystem(Char c, Char quote, DtdNotationToken decl)
        {
            stringBuffer.Clear();

            while (true)
            {
                if (c == Specification.EOF)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    src.Back();
                    decl.SystemIdentifier = stringBuffer.ToString();
                    return decl;
                }
                else if (c == Specification.NULL)
                {
                    RaiseErrorOccurred(ErrorCode.NULL);
                    stringBuffer.Append(Specification.REPLACEMENT);
                }
                else if (c == quote)
                {
                    decl.SystemIdentifier = stringBuffer.ToString();
                    return NotationDeclarationAfterSystem(src.Next, decl);
                }
                else if (c.IsPubidChar())
                    stringBuffer.Append(c);
                else
                    RaiseErrorOccurred(ErrorCode.InvalidCharacter);

                c = src.Next;
            }
        }
コード例 #5
0
        DtdNotationToken NotationDeclarationBeforePublic(Char c, DtdNotationToken decl)
        {
            while (c.IsSpaceCharacter())
            {
                c = _src.Next;
            }

            if (c == Specification.GT)
            {
                RaiseErrorOccurred(ErrorCode.TagClosedWrong);
                return(decl);
            }
            else if (c == Specification.EOF)
            {
                RaiseErrorOccurred(ErrorCode.EOF);
                _src.Back();
                return(decl);
            }
            else if (c == Specification.SQ)
            {
                return(NotationDeclarationPublic(_src.Next, Specification.SQ, decl));
            }
            else if (c == Specification.DQ)
            {
                return(NotationDeclarationPublic(_src.Next, Specification.DQ, decl));
            }
            else
            {
                return(NotationDeclarationAfterSystem(c, decl));
            }
        }
コード例 #6
0
        DtdNotationToken NotationDeclarationBeforeSystem(Char c, DtdNotationToken decl)
        {
            while (c.IsSpaceCharacter())
                c = src.Next;

            if (c == Specification.GT)
            {
                RaiseErrorOccurred(ErrorCode.TagClosedWrong);
                return decl;
            }
            else if (c == Specification.EOF)
            {
                RaiseErrorOccurred(ErrorCode.EOF);
                src.Back();
                return decl;
            }
            else if (c == Specification.SQ)
            {
                return NotationDeclarationSystem(src.Next, Specification.SQ, decl);
            }
            else if (c == Specification.DQ)
            {
                return NotationDeclarationSystem(src.Next, Specification.DQ, decl);
            }
            else
            {
                RaiseErrorOccurred(ErrorCode.NotationSystemInvalid);
                return decl;
            }
        }
コード例 #7
0
        DtdNotationToken NotationDeclarationPublic(Char c, Char quote, DtdNotationToken decl)
        {
            stringBuffer.Clear();

            while (true)
            {
                if (c == Specification.EOF)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    src.Back();
                    decl.PublicIdentifier = stringBuffer.ToString();
                    return decl;
                }
                else if (c == Specification.NULL)
                {
                    RaiseErrorOccurred(ErrorCode.NULL);
                    stringBuffer.Append(Specification.REPLACEMENT);
                }
                else if (c == quote)
                {
                    decl.PublicIdentifier = stringBuffer.ToString();
                    return NotationDeclarationAfterPublic(src.Next, decl);
                }
                else
                    stringBuffer.Append(c);

                c = src.Next;
            }
        }
コード例 #8
0
ファイル: DtdTokenizer.cs プロジェクト: Rajbandi/AngleSharp
        DtdNotationToken NotationDeclarationSystem(Char c, Char quote, DtdNotationToken decl)
        {
            _stringBuffer.Clear();

            while (true)
            {
                if (c == Specification.EOF)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    _src.Back();
                    decl.SystemIdentifier = _stringBuffer.ToString();
                    return decl;
                }
                else if (c == Specification.NULL)
                {
                    RaiseErrorOccurred(ErrorCode.NULL);
                    _stringBuffer.Append(Specification.REPLACEMENT);
                }
                else if (c == quote)
                {
                    decl.SystemIdentifier = _stringBuffer.ToString();
                    return NotationDeclarationAfterSystem(_src.Next, decl);
                }
                else if (c.IsPubidChar())
                    _stringBuffer.Append(c);
                else
                    RaiseErrorOccurred(ErrorCode.InvalidCharacter);

                c = _src.Next;
            }
        }
コード例 #9
0
        DtdNotationToken NotationDeclarationPublic(Char c, Char quote, DtdNotationToken decl)
        {
            _stringBuffer.Clear();

            while (c != quote)
            {
                if (c == Specification.EOF)
                    throw Errors.Xml(ErrorCode.DtdNotationInvalid);
                else if (!c.IsPubidChar())
                    throw Errors.Xml(ErrorCode.XmlInvalidPubId);

                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            decl.PublicIdentifier = _stringBuffer.ToString();
            return NotationDeclarationAfterPublic(_stream.Next, decl);
        }
コード例 #10
0
ファイル: DtdTokenizer.cs プロジェクト: Rajbandi/AngleSharp
        DtdNotationToken NotationDeclarationAfterSystem(Char c, DtdNotationToken decl)
        {
            var hasError = false;

            while (true)
            {
                if (c == Specification.GT)
                {
                    return decl;
                }
                else if (c == Specification.EOF)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    _src.Back();
                    return decl;
                }
                else if (!c.IsSpaceCharacter())
                {
                    if (!hasError)
                        RaiseErrorOccurred(ErrorCode.InputUnexpected);

                    hasError = true;
                }

                c = _src.Next;
            }
        }
コード例 #11
0
ファイル: DtdTokenizer.cs プロジェクト: Rajbandi/AngleSharp
        DtdNotationToken NotationDeclarationAfterPublic(Char c, DtdNotationToken decl)
        {
            while (c.IsSpaceCharacter())
                c = _src.Next;

            if (c == Specification.GT)
            {
                return decl;
            }
            else if (c == Specification.EOF)
            {
                RaiseErrorOccurred(ErrorCode.EOF);
                _src.Back();
                return decl;
            }
            else if (c == Specification.SQ)
            {
                return NotationDeclarationSystem(_src.Next, Specification.SQ, decl);
            }
            else if (c == Specification.DQ)
            {
                return NotationDeclarationSystem(_src.Next, Specification.DQ, decl);
            }
            else
            {
                return NotationDeclarationAfterSystem(c, decl);
            }
        }
コード例 #12
0
ファイル: DtdTokenizer.cs プロジェクト: Rajbandi/AngleSharp
        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#Notations.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdNotationToken NotationDeclaration(Char c)
        {
            var decl = new DtdNotationToken();
            var canContinue = false;

            if (c.IsSpaceCharacter())
                canContinue = DeclarationNameBefore(_src.Next, decl);
            else if (c == Specification.EOF)
                throw new ArgumentException("The document ended unexpectedly.");
            else
            {
                RaiseErrorOccurred(ErrorCode.UndefinedMarkupDeclaration);
                canContinue = DeclarationNameBefore(c, decl);
            }

            if (canContinue)
            {
                if (_src.ContinuesWith("PUBLIC", false))
                {
                    _src.Advance(5);
                    return NotationDeclarationBeforePublic(_src.Next, decl);
                }
                else if (_src.ContinuesWith("SYSTEM", false))
                {
                    _src.Advance(5);
                    return NotationDeclarationBeforeSystem(_src.Next, decl);
                }

                return NotationDeclarationAfterSystem(c, decl);
            }

            RaiseErrorOccurred(ErrorCode.NotationPublicInvalid);
            return decl;
        }
コード例 #13
0
        DtdNotationToken NotationDeclarationAfterSystem(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
                c = SkipSpaces(c);
            
            if (c == Specification.GT)
                return decl;

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }
コード例 #14
0
        DtdNotationToken NotationDeclarationSystem(Char c, Char quote, DtdNotationToken decl)
        {
            _stringBuffer.Clear();

            while (c != quote)
            {
                if (c == Specification.EOF)
                    throw Errors.Xml(ErrorCode.DtdNotationInvalid);

                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            decl.SystemIdentifier = _stringBuffer.ToString();
            return NotationDeclarationAfterSystem(_stream.Next, decl);
        }
コード例 #15
0
        DtdNotationToken NotationDeclarationBeforeSystem(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                while (c.IsSpaceCharacter())
                    c = _stream.Next;

                if (c == Specification.SQ || c == Specification.DQ)
                    return NotationDeclarationSystem(_stream.Next, c, decl);
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }
コード例 #16
0
        DtdNotationToken NotationDeclarationAfterPublic(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);

                if (c == Specification.SQ || c == Specification.DQ)
                    return NotationDeclarationSystem(_stream.Next, c, decl);
            }

            if (c == Specification.GT)
                return decl;

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }
コード例 #17
0
ファイル: DtdTokenizer.cs プロジェクト: Rajbandi/AngleSharp
        DtdNotationToken NotationDeclarationBeforeSystem(Char c, DtdNotationToken decl)
        {
            while (c.IsSpaceCharacter())
                c = _src.Next;

            if (c == Specification.GT)
            {
                RaiseErrorOccurred(ErrorCode.TagClosedWrong);
                return decl;
            }
            else if (c == Specification.EOF)
            {
                RaiseErrorOccurred(ErrorCode.EOF);
                _src.Back();
                return decl;
            }
            else if (c == Specification.SQ)
            {
                return NotationDeclarationSystem(_src.Next, Specification.SQ, decl);
            }
            else if (c == Specification.DQ)
            {
                return NotationDeclarationSystem(_src.Next, Specification.DQ, decl);
            }
            else
            {
                RaiseErrorOccurred(ErrorCode.NotationSystemInvalid);
                return decl;
            }
        }
コード例 #18
0
ファイル: DtdTokenizer.cs プロジェクト: Rajbandi/AngleSharp
        DtdNotationToken NotationDeclarationPublic(Char c, Char quote, DtdNotationToken decl)
        {
            _stringBuffer.Clear();

            while (true)
            {
                if (c == Specification.EOF)
                {
                    RaiseErrorOccurred(ErrorCode.EOF);
                    _src.Back();
                    decl.PublicIdentifier = _stringBuffer.ToString();
                    return decl;
                }
                else if (c == Specification.NULL)
                {
                    RaiseErrorOccurred(ErrorCode.NULL);
                    _stringBuffer.Append(Specification.REPLACEMENT);
                }
                else if (c == quote)
                {
                    decl.PublicIdentifier = _stringBuffer.ToString();
                    return NotationDeclarationAfterPublic(_src.Next, decl);
                }
                else
                    _stringBuffer.Append(c);

                c = _src.Next;
            }
        }
コード例 #19
0
        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#sec-comments.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdToken CommentEnd(Char c)
        {
            if (c == Specification.GT)
            {
                return new DtdCommentToken()
                       {
                           Data = _stringBuffer.ToString()
                       }
            }
            ;

            throw Errors.Xml(ErrorCode.XmlInvalidComment);
        }

        #endregion

        #region Declaration Name

        Boolean DeclarationNameBefore(Char c, DtdToken decl)
        {
            while (c.IsSpaceCharacter())
            {
                c = _stream.Next;
            }

            if (c == Specification.EOF)
            {
                throw Errors.Xml(ErrorCode.EOF);
            }

            if (c == Specification.PERCENT)
            {
                PEReference(_stream.Next);
                return(DeclarationNameBefore(_stream.Current, decl));
            }

            if (c.IsXmlNameStart())
            {
                _stringBuffer.Clear();
                _stringBuffer.Append(c);
                return(DeclarationName(_stream.Next, decl));
            }

            return(false);
        }

        Boolean DeclarationName(Char c, DtdToken decl)
        {
            while (c.IsXmlName())
            {
                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            if (c == Specification.PERCENT)
            {
                PEReference(_stream.Next);
                return(DeclarationName(_stream.Current, decl));
            }

            decl.Name = _stringBuffer.ToString();
            _stringBuffer.Clear();

            if (c == Specification.EOF)
            {
                throw Errors.Xml(ErrorCode.EOF);
            }

            return(c.IsSpaceCharacter());
        }

        #endregion

        #region Entity Declaration

        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#sec-entity-decl.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdToken EntityDeclaration(Char c)
        {
            var decl = new DtdEntityToken();

            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);
            }

            if (c == Specification.PERCENT)
            {
                decl.IsParameter = true;

                if (!_stream.Next.IsSpaceCharacter())
                {
                    throw Errors.Xml(ErrorCode.CharacterReferenceInvalidCode);
                }

                c = SkipSpaces(c);
            }

            if (DeclarationNameBefore(c, decl))
            {
                c = SkipSpaces(c);

                if (_stream.ContinuesWith(SYSTEM))
                {
                    decl.IsExtern = true;
                    _stream.Advance(5);
                    return(EntityDeclarationBeforeSystem(_stream.Next, decl));
                }
                else if (_stream.ContinuesWith(PUBLIC))
                {
                    decl.IsExtern = true;
                    _stream.Advance(5);
                    return(EntityDeclarationBeforePublic(_stream.Next, decl));
                }
                else if (Specification.DQ == c || Specification.SQ == c)
                {
                    _stringBuffer.Clear();
                    return(EntityDeclarationValue(_stream.Next, c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdEntityInvalid);
        }

        DtdToken EntityDeclarationBeforeValue(Char c, DtdEntityToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);

                if (Specification.DQ == c || Specification.SQ == c)
                {
                    return(EntityDeclarationValue(_stream.Next, c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdEntityInvalid);
        }

        DtdToken EntityDeclarationValue(Char c, Char end, DtdEntityToken decl)
        {
            decl.Value = ScanString(c, end);
            return(EntityDeclarationAfter(_stream.Next, decl));
        }

        DtdToken EntityDeclarationBeforePublic(Char c, DtdEntityToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);
                _stringBuffer.Clear();

                if (Specification.DQ == c || Specification.SQ == c)
                {
                    return(EntityDeclarationPublic(_stream.Next, c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdEntityInvalid);
        }

        DtdToken EntityDeclarationPublic(Char c, Char quote, DtdEntityToken decl)
        {
            while (c != quote)
            {
                if (!c.IsPubidChar())
                {
                    throw Errors.Xml(ErrorCode.DtdEntityInvalid);
                }

                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            decl.PublicIdentifier = _stringBuffer.ToString();
            return(EntityDeclarationBeforeSystem(_stream.Next, decl));
        }

        DtdToken EntityDeclarationBeforeSystem(Char c, DtdEntityToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);
                _stringBuffer.Clear();

                if (Specification.DQ == c || Specification.SQ == c)
                {
                    return(EntityDeclarationSystem(_stream.Next, c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdEntityInvalid);
        }

        DtdToken EntityDeclarationSystem(Char c, Char quote, DtdEntityToken decl)
        {
            while (c != quote)
            {
                if (c == Specification.EOF)
                {
                    throw Errors.Xml(ErrorCode.DtdEntityInvalid);
                }

                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            decl.SystemIdentifier = _stringBuffer.ToString();
            return(EntityDeclarationAfter(_stream.Next, decl));
        }

        DtdToken EntityDeclarationAfter(Char c, DtdEntityToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);

                if (decl.IsExtern && !decl.IsParameter && String.IsNullOrEmpty(decl.ExternNotation) && _stream.ContinuesWith(NDATA))
                {
                    _stream.Advance(4);
                    c = _stream.Next;

                    while (c.IsSpaceCharacter())
                    {
                        c = _stream.Next;
                    }

                    if (c.IsXmlNameStart())
                    {
                        _stringBuffer.Clear();

                        do
                        {
                            _stringBuffer.Append(c);
                            c = _stream.Next;
                        }while (c.IsXmlName());

                        decl.ExternNotation = _stringBuffer.ToString();
                        return(EntityDeclarationAfter(c, decl));
                    }

                    throw Errors.Xml(ErrorCode.DtdEntityInvalid);
                }
            }

            if (c == Specification.EOF)
            {
                throw Errors.Xml(ErrorCode.EOF);
            }
            else if (c == Specification.GT)
            {
                return(decl);
            }

            throw Errors.Xml(ErrorCode.DtdEntityInvalid);
        }

        #endregion

        #region Attribute Declaration

        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#attdecls.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdAttributeToken AttributeDeclaration(Char c)
        {
            var decl = new DtdAttributeToken();

            if (DeclarationNameBefore(_stream.Next, decl))
            {
                c = SkipSpaces(c);

                while (true)
                {
                    if (c == Specification.GT)
                    {
                        return(AttributeDeclarationAfter(c, decl));
                    }
                    else if (!c.IsXmlNameStart())
                    {
                        break;
                    }

                    _stringBuffer.Clear();
                    decl.Attributes.Add(AttributeDeclarationName(c));
                    c = _stream.Current;

                    if (c.IsSpaceCharacter())
                    {
                        c = SkipSpaces(c);
                    }
                }
            }

            throw Errors.Xml(ErrorCode.DtdAttListInvalid);
        }

        AttributeDeclarationEntry AttributeDeclarationName(Char c)
        {
            var value = new AttributeDeclarationEntry();

            do
            {
                _stringBuffer.Append(c);
                c = _stream.Next;
            }while (c.IsXmlName());

            if (!c.IsSpaceCharacter())
            {
                throw Errors.Xml(ErrorCode.DtdAttListInvalid);
            }

            value.Name = _stringBuffer.ToString();
            _stringBuffer.Clear();
            return(AttributeDeclarationType(_stream.Next, value));
        }

        AttributeDeclarationEntry AttributeDeclarationType(Char c, AttributeDeclarationEntry value)
        {
            while (c.IsSpaceCharacter())
            {
                c = _stream.Next;
            }

            if (c == Specification.RBO)
            {
                var type = new AttributeEnumeratedType();
                value.Type = type;
                AttributeDeclarationTypeEnumeration(_stream.Next, type);
            }
            else if (c.IsUppercaseAscii())
            {
                var id = String.Empty;

                while (true)
                {
                    if (c.IsSpaceCharacter())
                    {
                        id = _stringBuffer.ToString();
                        _stringBuffer.Clear();
                        break;
                    }
                    else if (c == Specification.GT)
                    {
                        throw Errors.Xml(ErrorCode.DtdAttListInvalid);
                    }
                    else if (c == Specification.NULL)
                    {
                        RaiseErrorOccurred(ErrorCode.NULL);
                        _stringBuffer.Append(Specification.REPLACEMENT);
                    }
                    else if (c == Specification.EOF)
                    {
                        throw Errors.Xml(ErrorCode.EOF);
                    }
                    else
                    {
                        _stringBuffer.Append(c);
                    }

                    c = _stream.Next;
                }

                switch (id)
                {
                case CDATA:
                    value.Type = new AttributeStringType();
                    break;

                case ID:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.ID
                    };
                    break;

                case IDREF:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.IDREF
                    };
                    break;

                case IDREFS:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.IDREFS
                    };
                    break;

                case ENTITY:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.ENTITY
                    };
                    break;

                case ENTITIES:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.ENTITIES
                    };
                    break;

                case NMTOKEN:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.NMTOKEN
                    };
                    break;

                case NMTOKENS:
                    value.Type = new AttributeTokenizedType {
                        Value = AttributeTokenizedType.TokenizedType.NMTOKENS
                    };
                    break;

                case NOTATION:
                    var type = new AttributeEnumeratedType {
                        IsNotation = true
                    };
                    value.Type = type;

                    while (c.IsSpaceCharacter())
                    {
                        c = _stream.Next;
                    }

                    if (c != Specification.RBO)
                    {
                        throw Errors.Xml(ErrorCode.DtdAttListInvalid);
                    }

                    AttributeDeclarationTypeEnumeration(_stream.Next, type);
                    break;

                default:
                    throw Errors.Xml(ErrorCode.DtdAttListInvalid);
                }
            }

            return(AttributeDeclarationValue(_stream.Next, value));
        }

        void AttributeDeclarationTypeEnumeration(Char c, AttributeEnumeratedType parent)
        {
            while (true)
            {
                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                if (c == Specification.EOF)
                {
                    throw Errors.Xml(ErrorCode.EOF);
                }

                if (!c.IsXmlName())
                {
                    throw Errors.Xml(ErrorCode.DtdAttListInvalid);
                }

                do
                {
                    _stringBuffer.Append(c);
                    c = _stream.Next;
                }while (c.IsXmlName());

                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                parent.Names.Add(_stringBuffer.ToString());
                _stringBuffer.Clear();

                if (c == Specification.RBC)
                {
                    break;
                }
                else if (c == Specification.PIPE)
                {
                    c = _stream.Next;
                }
                else
                {
                    throw Errors.Xml(ErrorCode.DtdAttListInvalid);
                }
            }
        }

        AttributeDeclarationEntry AttributeDeclarationValue(Char c, AttributeDeclarationEntry value)
        {
            while (c.IsSpaceCharacter())
            {
                c = _stream.Next;
            }

            var isfixed = false;

            if (c == Specification.NUM)
            {
                do
                {
                    _stringBuffer.Append(c);
                    c = _stream.Next;

                    if (c == Specification.EOF)
                    {
                        throw Errors.Xml(ErrorCode.EOF);
                    }
                    else if (c == Specification.GT)
                    {
                        break;
                    }
                }while (!c.IsSpaceCharacter());

                var tag = _stringBuffer.ToString();
                _stringBuffer.Clear();

                switch (tag)
                {
                case REQUIRED:
                    value.Default = new AttributeRequiredValue();
                    return(value);

                case IMPLIED:
                    value.Default = new AttributeImpliedValue();
                    return(value);

                case FIXED:
                    isfixed = true;
                    break;
                }

                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }
            }

            var defvalue = AttributeDeclarationBeforeDefaultValue(c);

            _stream.Advance();

            value.Default = new AttributeCustomValue
            {
                Value   = defvalue,
                IsFixed = isfixed
            };
            return(value);
        }

        String AttributeDeclarationBeforeDefaultValue(Char c)
        {
            if (c == Specification.DQ || c == Specification.SQ)
            {
                return(ScanString(_stream.Next, c));
            }

            throw Errors.Xml(ErrorCode.DtdAttListInvalid);
        }

        DtdAttributeToken AttributeDeclarationAfter(Char c, DtdAttributeToken decl)
        {
            while (c.IsSpaceCharacter())
            {
                c = _stream.Next;
            }

            if (c == Specification.GT)
            {
                return(decl);
            }

            throw Errors.Xml(ErrorCode.DtdAttListInvalid);
        }

        #endregion

        #region Notation Declaration

        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#Notations.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdNotationToken NotationDeclaration(Char c)
        {
            if (c.IsSpaceCharacter())
            {
                var decl = new DtdNotationToken();

                if (DeclarationNameBefore(_stream.Next, decl))
                {
                    c = SkipSpaces(c);

                    if (_stream.ContinuesWith(PUBLIC))
                    {
                        _stream.Advance(5);
                        return(NotationDeclarationBeforePublic(_stream.Next, decl));
                    }
                    else if (_stream.ContinuesWith(SYSTEM))
                    {
                        _stream.Advance(5);
                        return(NotationDeclarationBeforeSystem(_stream.Next, decl));
                    }

                    return(NotationDeclarationAfterSystem(c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }

        DtdNotationToken NotationDeclarationBeforePublic(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                if (c == Specification.SQ || c == Specification.DQ)
                {
                    return(NotationDeclarationPublic(_stream.Next, c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }

        DtdNotationToken NotationDeclarationPublic(Char c, Char quote, DtdNotationToken decl)
        {
            _stringBuffer.Clear();

            while (c != quote)
            {
                if (c == Specification.EOF)
                {
                    throw Errors.Xml(ErrorCode.DtdNotationInvalid);
                }
                else if (!c.IsPubidChar())
                {
                    throw Errors.Xml(ErrorCode.XmlInvalidPubId);
                }

                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            decl.PublicIdentifier = _stringBuffer.ToString();
            return(NotationDeclarationAfterPublic(_stream.Next, decl));
        }

        DtdNotationToken NotationDeclarationAfterPublic(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);

                if (c == Specification.SQ || c == Specification.DQ)
                {
                    return(NotationDeclarationSystem(_stream.Next, c, decl));
                }
            }

            if (c == Specification.GT)
            {
                return(decl);
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }

        DtdNotationToken NotationDeclarationBeforeSystem(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                if (c == Specification.SQ || c == Specification.DQ)
                {
                    return(NotationDeclarationSystem(_stream.Next, c, decl));
                }
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }

        DtdNotationToken NotationDeclarationSystem(Char c, Char quote, DtdNotationToken decl)
        {
            _stringBuffer.Clear();

            while (c != quote)
            {
                if (c == Specification.EOF)
                {
                    throw Errors.Xml(ErrorCode.DtdNotationInvalid);
                }

                _stringBuffer.Append(c);
                c = _stream.Next;
            }

            decl.SystemIdentifier = _stringBuffer.ToString();
            return(NotationDeclarationAfterSystem(_stream.Next, decl));
        }

        DtdNotationToken NotationDeclarationAfterSystem(Char c, DtdNotationToken decl)
        {
            if (c.IsSpaceCharacter())
            {
                c = SkipSpaces(c);
            }

            if (c == Specification.GT)
            {
                return(decl);
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }

        #endregion

        #region Type Declaration

        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#elemdecls.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdElementToken TypeDeclaration(Char c)
        {
            var decl = new DtdElementToken();

            if (DeclarationNameBefore(c, decl))
            {
                c = SkipSpaces(c);

                if (c == Specification.RBO)
                {
                    return(TypeDeclarationBeforeContent(_stream.Next, decl));
                }
                else if (_stream.ContinuesWith(ANY))
                {
                    _stream.Advance(2);
                    decl.Entry = ElementDeclarationEntry.Any;
                    return(TypeDeclarationAfterContent(_stream.Next, decl));
                }
                else if (_stream.ContinuesWith(EMPTY))
                {
                    _stream.Advance(4);
                    decl.Entry = ElementDeclarationEntry.Empty;
                    return(TypeDeclarationAfterContent(_stream.Next, decl));
                }

                return(TypeDeclarationAfterContent(c, decl));
            }

            throw Errors.Xml(ErrorCode.DtdTypeInvalid);
        }

        DtdElementToken TypeDeclarationBeforeContent(Char c, DtdElementToken decl)
        {
            while (c.IsSpaceCharacter())
            {
                c = _stream.Next;
            }

            if (_stream.ContinuesWith(PCDATA))
            {
                _stream.Advance(6);
                decl.Entry = TypeDeclarationMixed(_stream.Next);
            }
            else
            {
                decl.Entry = TypeDeclarationChildren(c);
            }

            return(TypeDeclarationAfterContent(_stream.Current, decl));
        }

        ElementChildrenDeclarationEntry TypeDeclarationChildren(Char c)
        {
            var entries    = new List <ElementQuantifiedDeclarationEntry>();
            var connection = Specification.NULL;

            while (true)
            {
                if (entries.Count > 0)
                {
                    if (c != Specification.PIPE && c != Specification.COMMA)
                    {
                        throw Errors.Xml(ErrorCode.DtdTypeContent);
                    }

                    if (entries.Count == 1)
                    {
                        connection = c;
                    }
                    else if (connection != c)
                    {
                        throw Errors.Xml(ErrorCode.DtdTypeContent);
                    }

                    c = _stream.Next;
                }

                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                if (c.IsXmlNameStart())
                {
                    var name = TypeDeclarationName(c);
                    entries.Add(name);
                }
                else if (c == Specification.RBO)
                {
                    entries.Add(TypeDeclarationChildren(_stream.Next));
                }
                else
                {
                    throw Errors.Xml(ErrorCode.DtdTypeContent);
                }

                c = _stream.Current;

                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                if (c == Specification.RBC)
                {
                    break;
                }
            }

            c = _stream.Next;

            if (entries.Count == 0)
            {
                throw Errors.Xml(ErrorCode.DtdTypeInvalid);
            }

            if (connection == Specification.COMMA)
            {
                var sequence = new ElementSequenceDeclarationEntry();
                sequence.Sequence.AddRange(entries);
                sequence.Quantifier = TypeDeclarationQuantifier(c);
                return(sequence);
            }
            else
            {
                var choice = new ElementChoiceDeclarationEntry();
                choice.Choice.AddRange(entries);
                choice.Quantifier = TypeDeclarationQuantifier(c);
                return(choice);
            }
        }

        ElementNameDeclarationEntry TypeDeclarationName(Char c)
        {
            _stringBuffer.Clear();
            _stringBuffer.Append(c);

            while ((c = _stream.Next).IsXmlName())
            {
                _stringBuffer.Append(c);
            }

            return(new ElementNameDeclarationEntry
            {
                Name = _stringBuffer.ToString(),
                Quantifier = TypeDeclarationQuantifier(c)
            });
        }

        ElementQuantifier TypeDeclarationQuantifier(Char c)
        {
            switch (c)
            {
            case Specification.ASTERISK:
                _stream.Advance();
                return(ElementQuantifier.ZeroOrMore);

            case Specification.QM:
                _stream.Advance();
                return(ElementQuantifier.ZeroOrOne);

            case Specification.PLUS:
                _stream.Advance();
                return(ElementQuantifier.OneOrMore);

            default:
                return(ElementQuantifier.One);
            }
        }

        ElementMixedDeclarationEntry TypeDeclarationMixed(Char c)
        {
            var entry = new ElementMixedDeclarationEntry();

            while (true)
            {
                while (c.IsSpaceCharacter())
                {
                    c = _stream.Next;
                }

                if (c == Specification.RBC)
                {
                    c = _stream.Next;

                    if (c == Specification.ASTERISK)
                    {
                        entry.Quantifier = ElementQuantifier.ZeroOrMore;
                        _stream.Advance();
                        return(entry);
                    }

                    if (entry.Names.Count == 0)
                    {
                        break;
                    }
                }
                else if (c == Specification.PIPE)
                {
                    c = _stream.Next;

                    while (c.IsSpaceCharacter())
                    {
                        c = _stream.Next;
                    }

                    _stringBuffer.Clear();

                    if (c.IsXmlNameStart())
                    {
                        _stringBuffer.Append(c);

                        while ((c = _stream.Next).IsXmlName())
                        {
                            _stringBuffer.Append(c);
                        }

                        entry.Names.Add(_stringBuffer.ToString());
                        continue;
                    }
                }

                throw Errors.Xml(ErrorCode.DtdTypeContent);
            }

            return(entry);
        }

        DtdElementToken TypeDeclarationAfterContent(Char c, DtdElementToken decl)
        {
            while (c.IsSpaceCharacter())
            {
                c = _stream.Next;
            }

            if (c == Specification.GT)
            {
                return(decl);
            }

            throw Errors.Xml(ErrorCode.DtdTypeInvalid);
        }

        #endregion
    }
コード例 #20
0
        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#Notations.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdNotationToken NotationDeclaration(Char c)
        {
            if (c.IsSpaceCharacter())
            {
                var decl = new DtdNotationToken();

                if (DeclarationNameBefore(_stream.Next, decl))
                {
                    c = SkipSpaces(c);

                    if (_stream.ContinuesWith(PUBLIC))
                    {
                        _stream.Advance(5);
                        return NotationDeclarationBeforePublic(_stream.Next, decl);
                    }
                    else if (_stream.ContinuesWith(SYSTEM))
                    {
                        _stream.Advance(5);
                        return NotationDeclarationBeforeSystem(_stream.Next, decl);
                    }

                    return NotationDeclarationAfterSystem(c, decl);
                }
            }

            throw Errors.Xml(ErrorCode.DtdNotationInvalid);
        }