/// <summary> /// Extracts XML-attributes from opening tag and adds them /// to the list af attributes of an object of xmlElement class. /// </summary> /// <param name="openingTag">Opening tag of an XML-element</param> /// <param name="element">Object of an xmlElement class</param> private static void AddAttributesToElement(StringBuilder openingTag, xmlElement element) { string attributes = ""; attributes = openingTag.ToString().Substring(openingTag.ToString().IndexOf(" "), element.Name.LastIndexOf("\"") - element.Name.IndexOf(" ") + 1); while (Regex.IsMatch(openingTag.ToString(), "=")) { int endOfAttributeValue = openingTag.ToString().IndexOf("\"") + 1; while (!openingTag[endOfAttributeValue].Equals('"')) { endOfAttributeValue++; } string attributeName = openingTag.ToString().Substring(openingTag.ToString().IndexOf(" ") + 1, openingTag.ToString().IndexOf("\"") - openingTag.ToString().IndexOf(" ") - 2); string attributeValue = openingTag.ToString().Substring(openingTag.ToString().IndexOf("\"") + 1, endOfAttributeValue - openingTag.ToString().IndexOf("\"") - 1); xmlAttribute attribute = new xmlAttribute(attributeName, attributeValue); element.Attributes.Add(attribute); openingTag.Replace(" " + attributeName + "=\"" + attributeValue + "\"", String.Empty); } }
/// <summary> /// Reccurently builds a tree of XML-Elements found in XML-string /// where each element have list of references to it's /// nested elements. Extracts each element body if presented. /// </summary> /// <param name="xmlString">XML-string ot parse</param> /// <param name="rootElement">Element to add found nested elements to</param> public static void Parse(string xmlString, xmlElement rootElement) { while (Regex.IsMatch(xmlString, openingTagPattern)) { StringBuilder elementName = new StringBuilder(); StringBuilder elementClosingTag = new StringBuilder(); StringBuilder tagContents = new StringBuilder(); StringBuilder openingTag = new StringBuilder(); Match element = Regex.Match(xmlString, openingTagPattern); openingTag.Append(element.Value); elementName.Append(GetElementName(element.Value)); // Constructing closing tag of an element elementClosingTag.Append(xmlString.Substring(xmlString.IndexOf("</" + elementName.ToString()), elementName.Length + 3)); // Extracting tag's contents tagContents.Append(xmlString.Substring(xmlString.IndexOf(element.Value) + element.Value.Length, xmlString.IndexOf(elementClosingTag.ToString()) - xmlString.IndexOf(element.Value)).Trim()); xmlElement newElement = new xmlElement(elementName.ToString()); // Extract attributes if presented if (Regex.IsMatch(element.Value, "=")) { AddAttributesToElement(openingTag, newElement); } // If there is nested tag inside current tag call ExtractElement for it, // else extract current tag body if (Regex.IsMatch(tagContents.ToString(), openingTagPattern)) { Parse(tagContents.ToString(), newElement); xmlString = xmlString.Remove(xmlString.IndexOf(element.Value), xmlString.IndexOf(elementClosingTag.ToString()) + elementClosingTag.ToString().Length).Trim(); } else { newElement.Body = tagContents.Replace(elementClosingTag.ToString().TrimEnd('>'), String.Empty).ToString(); xmlString = xmlString.Remove(xmlString.IndexOf(element.Value), xmlString.IndexOf(elementClosingTag.ToString()) + elementClosingTag.ToString().Length).Trim(); } rootElement.NestedElements.Add(newElement); } }
/// <summary> /// Entry point /// </summary> /// <param name="args"></param> static void Main(string[] args) { try { Console.OutputEncoding = System.Text.Encoding.UTF8; string xmlString = File.ReadAllText(@args[0]); xmlParser.RemoveComments(ref xmlString); xmlParser.RemoveXmlDeclaration(ref xmlString); xmlElement rootElement = new xmlElement("root"); xmlParser.Parse(xmlString, rootElement); rootElement.PrintRoot(); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } }