public override XmlParserState PushChar (char c, IXmlParserContext context, ref string rollback) { if (context.CurrentStateLength == 0) context.StateTag = 0; if (c == '<') { if (context.StateTag == 0) { context.StateTag++; return null; } } if (context.StateTag > 0) { if (CLOSE[context.StateTag] == c) { context.StateTag++; if (context.StateTag == CLOSE.Length) { var el = (XElement) context.Nodes.Pop (); var closing = new XClosingTag (new XName ("script"), context.LocationMinus (CLOSE.Length)); closing.End (context.Location); el.Close (closing); rollback = string.Empty; return Parent; } } else { context.StateTag = 0; } } return null; }
public override XmlParserState PushChar (char c, IXmlParserContext context, ref string rollback) { var ct = context.Nodes.Peek () as XClosingTag; if (ct == null) { Debug.Assert (context.CurrentStateLength == 1, "IncompleteNode must not be an XClosingTag when CurrentStateLength is 1"); ct = new XClosingTag (context.LocationMinus (3)); //3 = </ and the current char context.Nodes.Push (ct); } //if tag closed if (c == '>') { context.Nodes.Pop (); if (ct.IsNamed) { ct.End (context.Location); // walk up tree of parents looking for matching tag int popCount = 0; bool found = false; foreach (XObject node in context.Nodes) { popCount++; XElement element = node as XElement; if (element != null && element.Name == ct.Name) { found = true; break; } } if (!found) popCount = 0; //clear the stack of intermediate unclosed tags while (popCount > 1) { XElement el = context.Nodes.Pop () as XElement; if (el != null) context.LogError (string.Format ( "Unclosed tag '{0}' at line {1}, column {2}.", el.Name.FullName, el.Region.BeginLine, el.Region.BeginColumn), ct.Region); popCount--; } //close the start tag, if we found it if (popCount > 0) { if (context.BuildTree) ((XElement) context.Nodes.Pop ()).Close (ct); else context.Nodes.Pop (); } else { context.LogError ( "Closing tag '" + ct.Name.FullName + "' does not match any currently open tag.", ct.Region ); } } else { context.LogError ("Closing tag ended prematurely."); } return Parent; } if (c == '<') { context.LogError ("Unexpected '<' in tag.", context.LocationMinus (1)); context.Nodes.Pop (); rollback = string.Empty; return Parent; } if (XmlChar.IsWhitespace (c)) { return null; } if (!ct.IsNamed && (char.IsLetter (c) || c == '_')) { rollback = string.Empty; return NameState; } rollback = string.Empty; context.LogError ("Unexpected character '" + c + "' in closing tag.", context.LocationMinus (1)); context.Nodes.Pop (); return Parent; }