// parse tag private int ParseTag() { int LineNum = _Scanner.LineNum; int LinePos = _Scanner.LinePos; int token = _Scanner.ScanMarkup(); switch (token) { case XmlToken.TAG: _NextFunction = _ParseElementIndex; _CantHaveXmlDecl = true; _ContinueParsing = true; break; case XmlToken.EOF: return XmlToken.EOF; case XmlToken.PI: { LinePos += 2; //To Skip markup <? if (_Scanner.IsToken("xml")) { // // if xml is declared, there should not be any token before this // if it is from ResolveEntity(), xml decl is allowed and should // not be returned // if (_CantHaveXmlDecl) throw new XmlException(Res.Xml_XmlDeclNotFirst, LineNum, LinePos); if (_PIToken == null) _PIToken = new XmlNameValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.XmlDeclaration, -1, _Normalization); _PIToken.LineNum = LineNum; _PIToken.LinePos = LinePos; ParseXmlDecl(); if (_IsExternal) { _ContinueParsing = true; } else { _PIToken.Name = _NameTable.Add("xml"); _PIToken.SetValue(_StringBuilder); _PIToken.Depth = _ElementDepth + 1 + _EntityDepthOffset; _CurrentToken = _PIToken; } } else { bool hasBody = _Scanner.ScanPIName(); String name = _Scanner.GetTextAtom(); if (String.Compare(name, "xml", true, CultureInfo.InvariantCulture) == 0) throw new XmlException(Res.Xml_InvalidPIName, name, LineNum, LinePos); if (_CheckNamespaces && _Scanner.Colon() != -1) throw new XmlException(Res.Xml_InvalidPIName, name, LineNum, LinePos); if (_PIToken == null) _PIToken = new XmlNameValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.ProcessingInstruction, -1, _Normalization); _CantHaveXmlDecl = true; _PIToken.Name = name; _PIToken.NodeType = XmlNodeType.ProcessingInstruction; if (hasBody) { _Scanner.ScanPI(); _PIToken.SetValue(_Scanner, null, _Scanner.StartPos, _Scanner.TextLength); } else { _PIToken.Value = String.Empty; } _PIToken.Depth = _ElementDepth + 1 + _EntityDepthOffset; _CurrentToken = _PIToken; _Scanner.Advance(2); } } break; case XmlToken.COMMENT: LinePos += 4; //To Skip markup <!-- if (_CommentToken == null) _CommentToken = new XmlValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.Comment, -1, _Normalization); _CantHaveXmlDecl = true; _CommentToken.SetValue(_Scanner, null, _Scanner.StartPos, _Scanner.TextLength); _CommentToken.Depth = _ElementDepth + 1 + _EntityDepthOffset; _CurrentToken = _CommentToken; _Scanner.Advance(3); break; case XmlToken.CDATA: _CantHaveXmlDecl = true; LinePos += 9; //To skip the Markup <![CDATA[ if ((XmlNodeType.Document == _PartialContentNodeType || XmlNodeType.None == _PartialContentNodeType) && (_ElementStack.Length < 1 || _RootCount < 1)) throw new XmlException(Res.Xml_InvalidRootData, LineNum, LinePos); if (_CDATAToken == null) _CDATAToken = new XmlValueTokenInfo(_Scanner, _NsMgr, XmlNodeType.CDATA, -1, _Normalization); _CDATAToken.SetValue(_Scanner, null, _Scanner.StartPos, _Scanner.TextLength); _CDATAToken.Depth = _ElementDepth + 1 + _EntityDepthOffset; _CurrentToken = _CDATAToken; _Scanner.Advance(3); break; case XmlToken.DECL: { if (_DtdParser != null) { //A document cant have multiple doctyp throw new XmlException(Res.Xml_MultipleDTDsProvided, LineNum, LinePos); } if (_RootCount > 0) { throw new XmlException(Res.Xml_BadDTDLocation, LineNum, LinePos); } int startPos = _Scanner.CurrentPos-2; _Scanner.ReadBufferConsistency = _Scanner.StartPos; if (_DocTypeToken == null) _DocTypeToken = new XmlDtdTokenInfo(_Scanner, _NsMgr, XmlNodeType.DocumentType, -1, _Normalization); _CantHaveXmlDecl = true; _Used = -1; _DocTypeToken.Name = ParseDtd( _Scanner ); if (_DtdParser != null) { LinePos = _DtdParser.DTDNameStartPosition; LineNum = _DtdParser.DTDNameStartLine; } if (!_BufferConsistency) _Scanner.ReadBufferConsistency = -1; _DocTypeToken._DtdParser = _DtdParser; _DocTypeToken.Depth = _ElementDepth + 1 + _EntityDepthOffset; _CurrentToken = _DocTypeToken; } break; case XmlToken.ENDTAG: { LinePos += 2; //to skip the markup </ _Scanner.ScanNameWOCharChecking(); if (_LastElementInfo == null) { throw new XmlException(Res.Xml_UnexpectedEndTag, LineNum, LinePos); } int count = _Scanner.TextLength; char[] scannerbuff = _Scanner.InternalBuffer; if(_LastElementInfo._NameWPrefix.Length != count) { // The length of the start tag and end tag should be the same. // If it is not, no need to check char by char. goto errorCase; } int scannerOffset = _Scanner.TextOffset; for (int i = scannerOffset, j = 0; i < (scannerOffset + count) && j < count; i++, j++) { if (_LastElementInfo._NameWPrefix[j] != scannerbuff[i]) { goto errorCase; } } // // begin and end tag has to come from the same scanner // if (_LastElementInfo._Scanner != _Scanner) { throw new XmlException(Res.Xml_TagNotInTheSameEntity, _LastElementInfo._NameWPrefix, LineNum, LinePos); } _EndElementToken.SetName(_LastElementInfo._NameWPrefix, _LastElementInfo._LocalName, _LastElementInfo._Prefix, _LastElementInfo._NS, _ElementDepth + _EntityDepthOffset, _Scanner); _CurrentEndElementStart = _Scanner.StartPos-2; ReadEndElementToken(); _Scanner.ScanToken(XmlToken.TAGEND); // skip whitespace to the '>' _CurrentEndElementEnd = _Scanner.CurrentPos; _ElementDepth--; } break; } _CurrentToken.LineNum = LineNum; _CurrentToken.LinePos = LinePos; return token; errorCase: String[] args; string exceptionCode; if (String.Empty != _BaseURI) { args = new String[4]; args[3] = _BaseURI; exceptionCode = Res.Xml_TagMismatchFileName; } else { args = new String[3]; exceptionCode = Res.Xml_TagMismatch; } args[0] = _LastElementInfo._NameWPrefix; args[1] = _LastElementInfo._LineNumber.ToString(); args[2] = _Scanner.GetText(); throw new XmlException(exceptionCode, args, LineNum, LinePos); }
// protected constructor, users should not be using this /// <include file='doc\XmlTextReader.uex' path='docs/doc[@for="XmlTextReader.XmlTextReader1"]/*' /> /// <internalonly/> /// <devdoc> /// <para>Initializes a new instance of the XmlTextReader class with the specified XmlNameTable.</para> /// </devdoc> protected XmlTextReader( XmlNameTable nt ) { // // internal variables // _ElementDepth = -1; _EntityDepthOffset = 0; _ReadCount = -1; // // variables for properties // _ReadState = ReadState.Initial; _NextState = 1; // // create interal components // _NameTable = nt; _ElementStack = new HWStack(STACK_INCREMENT); _ScannerStack = new HWStack(STACK_INCREMENT); // //create atom // _StringName = _NameTable.Add("String"); _MicrosoftSystemNamespace = _NameTable.Add("System"); _Decimal = _NameTable.Add("#decimal"); _Hex = _NameTable.Add("#hexidecimal"); _Amp = _NameTable.Add("amp"); _Lt = _NameTable.Add("lt"); _Gt = _NameTable.Add("gt"); _Quot = _NameTable.Add("quot"); _Apos = _NameTable.Add("apos"); _XmlNs = _NameTable.Add("xmlns"); _XmlSpaceAtom = _NameTable.Add("xml:space"); _XmlLangAtom = _NameTable.Add("xml:lang"); // //fields collection // _Used = -1; _MarkScannerCount = 10000; // _XmlSpace = XmlSpace.None; _XmlLang = String.Empty; _WhitespaceHandling = WhitespaceHandling.All; _XmlResolver = new XmlUrlResolver(); _CheckNamespaces = true; _TmpToken = new XmlNSElementTokenInfo(_Scanner, _NsMgr, XmlNodeType.None, String.Empty,-1, -1, -1, 0,false); _CurrentToken = _TmpToken; // PERF: these node types are not common therefore they // will only be constructed when used // _CommentToken = null; _CDATAToken = null; _DocTypeToken = null; _PIToken = null; _EndEntityToken = null; _NextFunction = _InitReader; _StringBuilder = new StringBuilder(100); }