/// <summary> /// This method parses xml using a <c>StringReader</c> instance and returns an <c>Xml</c> instance /// containing the parsed data. /// </summary> /// <param name="stringReader">The <c>StringReader</c> instance containing the xml data to parse</param> /// <returns>An <c>Xml</c> instance containing the parsed data.</returns> public Xml Parse(StringReader stringReader) { using (XmlReader reader = XmlReader.Create(stringReader, _settings)) { Xml currentElement = null; Stack<Xml> elementStack = new Stack<Xml>(); while (reader.Read()) { switch (reader.NodeType) { // Handle Open Element, <element> case XmlNodeType.Element: Xml xmlElement = new Xml(reader.Name, reader.NamespaceURI); // Check for Attributes and Read All Attributes if (reader.HasAttributes) { while (reader.MoveToNextAttribute()) { xmlElement.AddAttribute(reader.Name, reader.Value); } // Move back to the element reader.MoveToElement(); } // Handles node that only contains attributes: <someNode x='10' y='5'/> if (!reader.HasValue && reader.IsEmptyElement) { currentElement.AppendElement(xmlElement); break; } elementStack.Push(xmlElement); if (currentElement == null) { currentElement = xmlElement; } else { currentElement.AppendElement(xmlElement); currentElement = xmlElement; } break; // Handle attribute or element text, ... prop="myProp" ... case XmlNodeType.Text: currentElement.Value = reader.Value; break; // Handle end element, </element> case XmlNodeType.EndElement: if (elementStack.Count > 1) { elementStack.Pop(); currentElement = elementStack.Peek(); } else if (elementStack.Count > 0) { elementStack.Pop(); } break; } } return currentElement; } }
/// <summary> /// This method sets the parent for the <c>Xml</c> node. /// </summary> /// <param name="parent"></param> private void SetParent(Xml parent) { _parent = parent; }
/// <summary> /// This method appends additional XML elements to this node. /// </summary> /// <param name="element"></param> public void AppendElement(Xml element) { if (_isUndefined) { throw new Exception("Cannot append elements to an undefined Xml node."); } if (!_elements.ContainsKey(element.Name)) { _elements[element.Name] = new List<Xml>(); } _elements[element.Name].Add(element); element.SetParent(this); }
/// <summary> /// This method creates a cloned copy of this instance and returns it. /// </summary> public Xml Clone() { if (_isUndefined) { throw new Exception("Cannot clone the undefined Xml node."); } Xml clone = new Xml(_name, _namespaceUri); foreach (string key in _attributes.Keys) { clone.AddAttribute(key, _attributes[key]); } foreach (Xml element in Elements) { clone.AppendElement(element); } clone.Value = Value; return clone; }
/// <summary> /// This static method compares two <c>Xml</c> instances and returns their /// equality based on their <c>Value</c> property. /// </summary> /// <param name="node1">The first node to compare</param> /// <param name="node2">The second node to compare</param> /// <returns>A <c>true</c> if the two nodes are equal, otherwise <c>false</c></returns> public static Boolean Equals(Xml node1, Xml node2) { if (Xml.ReferenceEquals(node1, node2)) { return true; } return node1.Equals(node2); }