using System; using System.Collections.Generic; public class XMLParser { public XMLParser(string xmlString) { this.xmlString = xmlString; } public XMLParser() { this.xmlString = string.Empty; } public XMLElement XMLRootElement { get { return this.rootElement; } } public string XMLString { get { return this.xmlString; } set { this.xmlString = value; this.rootflag = false; } } public virtual XMLElement Parse(string xmlString) { this.xmlString = xmlString; return this.Parse(); } public XMLElement Parse() { this.rootflag = false; string text = string.Empty; string tagName = string.Empty; string name = string.Empty; string arg = string.Empty; XMLTokenType xmltokenType = XMLTokenType.None; XMLTokenType xmltokenType2 = XMLTokenType.None; XMLParserAttrbuteMode xmlparserAttrbuteMode = XMLParserAttrbuteMode.Name; this.attributeList = new List(); int i = 0; int length = this.xmlString.Length; while (i < length) { char c = this.xmlString[i]; switch (c) { case ';': if (xmltokenType == XMLTokenType.Entity) { xmltokenType = xmltokenType2; text = arg + XMLParser.ParseEntityReference(text); } else { text += c; } break; case '<': { xmltokenType2 = xmltokenType; if (xmltokenType2 != XMLTokenType.Entity) { if (xmltokenType2 == XMLTokenType.Text) { this.TextHandler(text); } } else { this.EntityHandler(text); } char c2 = this.xmlString[i + 1]; if (c2 != '!') { if (c2 != '/') { if (c2 != '?') { if (xmltokenType2 != XMLTokenType.Declaration) { if (xmltokenType2 != XMLTokenType.EntityElement) { xmltokenType = XMLTokenType.StartElement; } else { xmltokenType = XMLTokenType.EntityElement; } } else { xmltokenType = XMLTokenType.Declaration; } } else { xmltokenType = XMLTokenType.Declaration; i++; } } else { xmltokenType = XMLTokenType.EndElement; i++; } } else { xmltokenType = XMLTokenType.EntityElement; i++; } text = string.Empty; break; } case '=': if (xmltokenType != XMLTokenType.Attribute) { text += c; } else if (xmlparserAttrbuteMode != XMLParserAttrbuteMode.Name) { if (xmlparserAttrbuteMode == XMLParserAttrbuteMode.Value) { text += c; } } else { name = text.Trim(); text = string.Empty; xmlparserAttrbuteMode = XMLParserAttrbuteMode.Assignment; } break; case '>': xmltokenType2 = xmltokenType; switch (xmltokenType) { case XMLTokenType.Declaration: this.DeclarationHandler(text); break; case XMLTokenType.EntityElement: this.EntityHandler(text); break; case XMLTokenType.StartElement: this.StartElementHandler(text); if (this.xmlString[i - 1] == '/') { this.EndElementHandler(text); } break; case XMLTokenType.EndElement: this.EndElementHandler(text); break; case XMLTokenType.Attribute: this.StartElementHandler(tagName); xmltokenType2 = XMLTokenType.StartElement; break; } text = string.Empty; xmltokenType = XMLTokenType.Text; break; default: switch (c) { case ' ': if (xmltokenType != XMLTokenType.StartElement) { if (xmltokenType != XMLTokenType.Text) { if (xmltokenType == XMLTokenType.Attribute) { if (xmlparserAttrbuteMode == XMLParserAttrbuteMode.Value) { text += c; } } } else { text += c; } } else { xmltokenType2 = xmltokenType; xmltokenType = XMLTokenType.Attribute; tagName = text; text = string.Empty; xmlparserAttrbuteMode = XMLParserAttrbuteMode.Name; } break; default: if (c != '&') { text += c; } else { xmltokenType2 = xmltokenType; xmltokenType = XMLTokenType.Entity; arg = text; text = string.Empty; } break; case '"': if (xmltokenType == XMLTokenType.Attribute) { if (xmlparserAttrbuteMode != XMLParserAttrbuteMode.Assignment) { if (xmlparserAttrbuteMode == XMLParserAttrbuteMode.Value) { this.AttributeHandler(name, text); text = string.Empty; xmlparserAttrbuteMode = XMLParserAttrbuteMode.Name; } } else { xmlparserAttrbuteMode = XMLParserAttrbuteMode.Value; } } break; } break; } i++; } return this.rootElement; } protected virtual void DeclarationHandler(string content) { } protected virtual void EntityHandler(string content) { } protected virtual void StartElementHandler(string tagName) { XMLElement xmlelement; if (!this.rootflag) { xmlelement = new XMLElement(tagName.Trim(), null); this.rootElement = xmlelement; this.rootflag = true; } else { xmlelement = new XMLElement(tagName.Trim(), this.currentElement); } int i = 0; int count = this.attributeList.Count; while (i < count) { xmlelement.Attributes.Add(this.attributeList[i]); i++; } this.attributeList = new List(); this.currentElement = xmlelement; } protected virtual void EndElementHandler(string tagName) { if (this.rootflag && this.rootElement != this.currentElement) { this.currentElement = (XMLElement)this.currentElement.Parent; } } protected virtual void AttributeHandler(string name, string value) { this.attributeList.Add(new XMLAttribute(name.Trim(), value)); } protected virtual void TextHandler(string text) { if (this.rootflag && text.Trim().Length > 0) { if (this.currentElement.Children.Count != 0) { IXMLNode ixmlnode = this.currentElement.Children[this.currentElement.Children.Count - 1]; if (ixmlnode.type == XMLNodeType.Text) { IXMLNode ixmlnode2 = ixmlnode; ixmlnode2.value += text; return; } } new XMLText(text, this.currentElement); } } public static char ParseEntityReference(string entity) { if (entity != null) { if (entity == "lt") { return '<'; } if (entity == "gt") { return '>'; } if (entity == "quot") { return '"'; } if (entity == "apos") { return '\''; } if (entity == "amp") { return '&'; } } return '\0'; } public static string GetEntityReference(char c) { if (c == '&') { return "&"; } if (c == '\'') { return "'"; } switch (c) { case '<': return "<"; default: if (c != '"') { return c.ToString(); } return """; case '>': return ">"; } } protected XMLElement rootElement; protected XMLElement currentElement; protected bool rootflag; protected List attributeList; protected string xmlString; }