/// <summary> /// Process a end tag /// </summary> /// <returns>Result of processing (true - is processed; false - is not processed)</returns> private bool ProcessEndTag() { bool isProcessed = false; string content = _innerContext.SourceCode; int contentRemainderLength = _innerContext.RemainderLength; var match = _endTagRegex.Match(content, _innerContext.Position, contentRemainderLength); if (match.Success) { string endTag = match.Value; string endTagName = match.Groups["tagName"].Value; if (_tagStack.Count == 0) { throw new XmlParsingException( string.Format(Strings.ErrorMessage_StartTagNotDeclared, endTagName), _innerContext.NodeCoordinates, _innerContext.GetSourceFragment()); } StackedXmlTag stackedTag = _tagStack.Pop(); if (stackedTag.Name != endTagName) { if (_tagStack.Count(t => t.Name == endTagName) > 0) { throw new XmlParsingException( string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name), stackedTag.Coordinates, SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates)); } throw new XmlParsingException( string.Format(Strings.ErrorMessage_StartTagNotDeclared, endTagName), _innerContext.NodeCoordinates, _innerContext.GetSourceFragment()); } if (_handlers.EndTag != null) { _handlers.EndTag(_context, endTagName); } _innerContext.IncreasePosition(endTag.Length); isProcessed = true; } return(isProcessed); }
/// <summary> /// Parses XML content /// </summary> /// <param name="content">XML content</param> public void Parse(string content) { int contentLength = content.Length; if (contentLength == 0) { return; } lock (_parsingSynchronizer) { _innerContext = new InnerMarkupParsingContext(content); _context = new MarkupParsingContext(_innerContext); _tagStack = new Stack <StackedXmlTag>(); int endPosition = contentLength - 1; int previousPosition = -1; try { while (_innerContext.Position <= endPosition) { bool isProcessed = false; if (content.CustomStartsWith("<", _innerContext.Position, StringComparison.Ordinal)) { if (content.CustomStartsWith("</", _innerContext.Position, StringComparison.Ordinal)) { // End tag isProcessed = ProcessEndTag(); } else if (content.CustomStartsWith("<!", _innerContext.Position, StringComparison.Ordinal)) { // XML comments isProcessed = ProcessComment(); if (!isProcessed) { // CDATA sections isProcessed = ProcessCdataSection(); } if (!isProcessed) { // Doctype declaration isProcessed = ProcessDoctype(); } } else if (content.CustomStartsWith("<?", _innerContext.Position, StringComparison.Ordinal)) { // XML declaration and processing instructions isProcessed = ProcessProcessingInstruction(); } else { // Start tag isProcessed = ProcessStartTag(); } } if (!isProcessed) { // Text ProcessText(); } if (_innerContext.Position == previousPosition) { throw new XmlParsingException( string.Format(Strings.ErrorMessage_MarkupParsingFailed, "XML"), _innerContext.NodeCoordinates, _innerContext.GetSourceFragment()); } previousPosition = _innerContext.Position; } // Check whether there were not closed tags if (_tagStack.Count > 0) { StackedXmlTag stackedTag = _tagStack.Pop(); throw new XmlParsingException( string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name), stackedTag.Coordinates, SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates)); } } catch (XmlParsingException) { throw; } finally { _tagStack.Clear(); _context = null; _innerContext = null; } } }
/// <summary> /// Parses XML content /// </summary> /// <param name="content">XML content</param> public void Parse(string content) { int contentLength = content.Length; if (contentLength == 0) { return; } lock (_parsingSynchronizer) { _innerContext = new InnerMarkupParsingContext(content); _context = new MarkupParsingContext(_innerContext); int endPosition = contentLength - 1; int previousPosition = -1; try { while (_innerContext.Position <= endPosition) { bool isProcessed = false; if (_innerContext.PeekCurrentChar() == '<') { switch (_innerContext.PeekNextChar()) { case char c when IsTagFirstChar(c): // Start tag isProcessed = ProcessStartTag(); break; case '/': if (IsTagFirstChar(_innerContext.PeekNextChar())) { // End tag isProcessed = ProcessEndTag(); } break; case '!': switch (_innerContext.PeekNextChar()) { case '-': if (_innerContext.PeekNextChar() == '-') { // XML comments isProcessed = ProcessComment(); } break; case '[': // CDATA sections isProcessed = ProcessCdataSection(); break; case 'D': // Doctype declaration isProcessed = ProcessDoctype(); break; } break; case '?': // XML declaration and processing instructions isProcessed = ProcessProcessingInstruction(); break; } } if (!isProcessed) { // Text ProcessText(); } if (_innerContext.Position == previousPosition) { throw new MarkupParsingException( string.Format(Strings.ErrorMessage_MarkupParsingFailed, "XML"), _innerContext.NodeCoordinates, _innerContext.GetSourceFragment()); } previousPosition = _innerContext.Position; } // Check whether there were not closed tags if (_tagStack.Count > 0) { StackedXmlTag stackedTag = _tagStack.Pop(); throw new MarkupParsingException( string.Format(Strings.ErrorMessage_NotClosedTag, stackedTag.Name), stackedTag.Coordinates, SourceCodeNavigator.GetSourceFragment(_innerContext.SourceCode, stackedTag.Coordinates)); } } catch (MarkupParsingException) { throw; } finally { _tagStack.Clear(); _context = null; _innerContext = null; } } }