// ---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // ---------------------------------------------------------------------------- namespace Microsoft.Singularity.Xml { using System; using System.Collections; using System.Globalization; /// /// Summary description for XmlNode. /// public class XmlNode { private string name; private int depth; private string text; private ArrayList attributes; private ArrayList children; private XmlNode parentNode; internal class XmlAttr { public readonly string name; public string value; internal XmlAttr(string name, string value) { this.name = name != null ? name : ""; this.value = value; } internal void WriteContentTo(XmlWriter w) { w.WriteString(this.value); } internal void WriteTo(XmlWriter w) { //w.WriteAttributeString(this.name, this.value); w.WriteStartAttribute(null, this.name, null); WriteContentTo(w); w.WriteEndAttribute(); } } public XmlNode() { attributes = new ArrayList(); children = new ArrayList(); this.text = ""; } public XmlNode(string name) { this.name = name != null ? name : ""; attributes = new ArrayList(); children = new ArrayList(); this.text = ""; } internal virtual XmlNode NullNode { get { return null; } } public void SetParent(XmlNode p) { this.parentNode = p; } public virtual XmlNode ParentNode { get { if (parentNode == NullNode) return null; return parentNode; } } public XmlNode(string name, int depth) { this.name = name; this.depth = depth; attributes = new ArrayList(); children = new ArrayList(); this.text = ""; } public XmlNode[] Children { get { XmlNode[] result; if (children == null) { result = new XmlNode[0]; } else { if (children.Count == 0) { result = new XmlNode[0]; } else { result = new XmlNode[children.Count]; int i = 0; foreach (XmlNode childNode in children) { result[i++] = childNode; } } } return result; } } public XmlNode CreateNode (string name) { XmlNode n = new XmlNode(); n.name = name; return n; } public XmlNode[] ChildNodes { get { return this.Children ;} } public ArrayList GetNamedChildren(string name) { ArrayList result = new ArrayList(); foreach (XmlNode childNode in children) { if (childNode.Name == name) { result.Add(childNode); } } return result; } public XmlNode GetChild(string name) { foreach (XmlNode childNode in children) { if (childNode.Name == name) { return childNode; } } return null; } public XmlNode GetNestedChild(String[] childNames) { XmlNode node = this; for (int i = 0; node != null && i < childNames.Length; i++) { node = node.GetNestedChild(childNames[i]); } return node; } public XmlNode GetNestedChild(String childName) { foreach (XmlNode childNode in children) { if (childNode.Name == childName) { return childNode; } } return null; } // override this /// /// Saves the current node to the specified XmlWriter. /// public virtual void WriteTo(XmlWriter w) { if (this.name == "::xml") { WriteContentTo(w); return; } w.WriteStartElement("", this.name, ""); if (attributes.Count > 0) { foreach (XmlAttr attr in attributes) { attr.WriteTo(w); } } if (children.Count > 0) { WriteContentTo(w); } if (children.Count == 0) w.WriteEndElement(); else w.WriteFullEndElement(); } // override this /// /// Saves all the children of the node to the specified XmlWriter. /// public virtual void WriteContentTo(XmlWriter w) { foreach (XmlNode n in children) { n.WriteTo(w); } } public int Depth { get { return depth; } } public string Name { get { return name; } } public void AddChild(XmlNode node) { children.Add(node); return; } public ArrayList ChildrenList { get { return new ArrayList(children); } } public void AddText(string text) { this.text += text; return; } public string Text { get { return text; } } public string this[string attributeName] { get { XmlAttr a = FindAttr(attributeName); if (a == null) return null; return a.value; } set { XmlAttr a = FindAttr(attributeName); if (a == null) { a = new XmlAttr(attributeName, value); attributes.Add(a); } else a.value = value; } } // // Safe access to attributes: // since the kernel is going to use this object, we should // push the error-checking into the object instead of risking // the kernel forgetting to error check in some obscure method // public string GetAttribute(string attributeName, string defaultValue) { XmlAttr a = FindAttr(attributeName); if (a == null) { return defaultValue; } else { return a.value; } } public bool GetAttribute(string attributeName, bool defaultValue) { XmlAttr a = FindAttr(attributeName); if (a == null) { return defaultValue; } else { return a.value == System.Boolean.TrueString; } } public int GetAttribute(string attributeName, int defaultValue) { XmlAttr a = FindAttr(attributeName); if (a == null) { return defaultValue; } else { string num = a.value; if (num.StartsWith("0x") || num.StartsWith("0X")) { return System.Int32.Parse(num, NumberStyles.AllowHexSpecifier); } else { return System.Int32.Parse(num); } } } public long GetAttribute(string attributeName, long defaultValue) { XmlAttr a = FindAttr(attributeName); if (a == null) { return defaultValue; } else { string num = a.value; if (num.StartsWith("0x") || num.StartsWith("0X")) { return System.Int64.Parse(num, NumberStyles.AllowHexSpecifier); } else { return System.Int64.Parse(num); } } } [CLSCompliant(false)] public UIntPtr GetAttributeAsUIntPtr(string attributeName, UIntPtr defaultValue) { XmlAttr a = FindAttr(attributeName); if (a == null) { return defaultValue; } else { string num = a.value; if (num.StartsWith("0x") || num.StartsWith("0X")) { return System.UIntPtr.Parse(num, NumberStyles.AllowHexSpecifier); } else { return System.UIntPtr.Parse(num); } } } public void PrependAttribute(string name, string value) { if (attributes == null) return; XmlAttr a = new XmlAttr(name,value); attributes.Insert(0,a); } public void AddAttribute(string name, string value) { if (attributes == null) return; XmlAttr a = new XmlAttr(name, value); attributes.Add(a); } public bool HasAttribute(string attributeName) { return (FindAttr(attributeName) != null) ; } private XmlAttr FindAttr(string name) { if (attributes == null) return null; foreach (XmlAttr attr in attributes) { if (attr.name == name) return attr; } return null; } public string GetAttributes() { string list = ""; foreach (DictionaryEntry entry in attributes) { list = list + " " + entry.Key.ToString() + "=\"" + entry.Value.ToString() + "\""; } return list; } } }