using System.Text; using System.Collections; using Cobilas.Collections; using System.Collections.Generic; using System.Linq; namespace System.Xml { /// XML improved reader and writer element. public class XMLIRWElement : XMLIRW, ITextValue, IXMLIRWCollection { private bool disposedValue; private XMLIRW[] itens; /// public XMLIRWText Text { get; set; } /// [Obsolete("Use the Text property.")] public XMLIRWValue Value { get; set; } /// public override XmlNodeType Type { get; set; } /// public override XMLIRW Parent { get; set; } = default; /// public bool ValueIsEmpty => Text is null || Text.IsNull; /// public override string Name { get; set; } = string.Empty; /// public bool IsEmpty => ArrayManipulation.EmpytArray(itens); /// public bool NoAttributes { get { if (!IsEmpty) foreach (var item in itens) if (item.Type == XmlNodeType.Attribute) return false; return true; } } /// public bool NoElements { get { if (!IsEmpty) foreach (var item in itens) if (item.Type != XmlNodeType.Attribute) return false; return true; } } /// public int AttributeCount { get { int res = 0; if (!NoAttributes) foreach (var item in itens) ++res; return res; } } /// public IEnumerable Attributes { get { if (!IsEmpty) foreach (var item in itens) if (item.Type == XmlNodeType.Attribute) yield return item; } } /// [Obsolete("Use the XMLIRWElement(XMLIRW, string, object, params XMLIRW[]) constructor.")] public XMLIRWElement(XMLIRW parent, string name, XMLIRWValue value, params XMLIRW[] itens) : base(parent, name, XmlNodeType.Element) { Name = name; this.itens = itens; this.Value = value; if (!ArrayManipulation.EmpytArray(itens)) foreach (var item in itens) item.Parent = this; } /// [Obsolete("Use the XMLIRWElement(XMLIRW, string, object) constructor.")] public XMLIRWElement(XMLIRW parent, string name, XMLIRWValue value) : this(parent, name, value, null) {} /// [Obsolete("Use the XMLIRWElement(string, object, params XMLIRW[]) constructor.")] public XMLIRWElement(string name, XMLIRWValue value, params XMLIRW[] itens) : this(null, name, value, itens) {} /// [Obsolete("Use the XMLIRWElement(string, object) constructor.")] public XMLIRWElement(string name, XMLIRWValue value) : this(null, name, value, null) {} /// public XMLIRWElement(XMLIRW parent, string name, object value, params XMLIRW[] itens) : base(parent, name, XmlNodeType.Element) { Name = name; this.Text = new XMLIRWText(value); if (!ArrayManipulation.EmpytArray(itens)) foreach (var item in itens) Add(item); } /// public XMLIRWElement(XMLIRW parent, string name, object value) : this(parent, name, value, null) {} /// public XMLIRWElement(XMLIRW parent, string name, params XMLIRW[] itens) : this(parent, name, null, itens) {} /// public XMLIRWElement(string name, object value, params XMLIRW[] itens) : this(null, name, value, itens) {} /// public XMLIRWElement(string name, object value) : this(null, name, value, null) {} /// public XMLIRWElement(string name, params XMLIRW[] itens) : this(null, name, null, itens) {} /// public XMLIRWElement(string name) : this(null, name, null) {} /// Called when the object is finished. ~XMLIRWElement() => Dispose(disposing: false); /// public override void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } /// public bool Add(XMLIRW element) { if (element is null) return false; if (element is XMLIRWText text) { (Text = text).Parent = this; return true; } element.Parent = this; ArrayManipulation.Add(element, ref itens); return true; } /// Returns an enumerator that iterates through a collection. public IEnumerator GetEnumerator() => new ArrayToIEnumerator(itens); /// public override string ToString() { StringBuilder builder = new StringBuilder(); foreach (var item in this) builder.Append(ToString(item, 0UL)); return builder.ToString(); } /// protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { Name = string.Empty; Parent = default; Type = default; ArrayManipulation.ClearArraySafe(ref itens); } disposedValue = true; } } IEnumerator IEnumerable.GetEnumerator() => new ArrayToIEnumerator(itens); private static string ToString(XMLIRW element, ulong tab) { StringBuilder builder = new StringBuilder(); if (element is XMLIRWElement ele) { builder.Append(GetTab(" ", tab)) .Append('>').AppendFormat("[{0}]", element.Name); if (!ele.NoAttributes) { builder.Append("()) builder.AppendFormat("{0}[{1}]", item.Name, item.Text); builder.Append(">"); } if (!ele.ValueIsEmpty) { builder.AppendLine(" {").AppendLine((string)ele.Text).Append(GetTab(" ", tab)) .AppendLine("}"); } else builder.AppendLine(" {}"); foreach (var item in ele) builder.Append(ToString(item, tab + 1)); } else if (element is XMLIRWComment cm) { builder.Append(GetTab(" ", tab)) .Append('>').AppendFormat("[{0}]", element.Name); string txt = (string)cm.Text; if (string.IsNullOrEmpty(txt)) builder.AppendLine(" {}"); else { builder.AppendLine(" {").AppendLine(txt).Append(GetTab(" ", tab)) .AppendLine("}"); } } else if (element is XMLIRWCDATA cd) { builder.Append(GetTab(" ", tab)) .Append('>').AppendFormat("[{0}<{1}>]\r\n", element.Name, cd.Text); } else if (element is XMLIRWDocType doc) { builder.Append(GetTab(" ", tab)) .Append('>').AppendFormat("[{0}]\r\n", element.Name, doc.PudID, doc.SysID, doc.SubSet); } else if (element is XMLIRWProcessingInstruction pi) { builder.Append(GetTab(" ", tab)) .Append('>').AppendFormat("[{0}<", element.Name); if (pi.IsAttributeList) { builder.Append("attris: "); foreach (XMLIRWAttribute item in pi) builder.AppendFormat("{0}[{1}]", item.Name, item.Text); builder.Append(">]\r\n"); } else builder.AppendFormat("{0}>]\r\n", pi.Text); } else if (element is XMLIRWDeclaration dec) { builder.Append(GetTab(" ", tab)) .Append('>').AppendFormat("[{0}<", element.Name); if (!string.IsNullOrEmpty(dec.Version)) builder.AppendFormat("version[{0}] ", dec.Version); if (!string.IsNullOrEmpty(dec.Encoding)) builder.AppendFormat("encoding[{0}] ", dec.Encoding); if (!string.IsNullOrEmpty(dec.Standalone)) builder.AppendFormat("standalone[{0}] ", dec.Standalone); builder.AppendLine(">]"); } return builder.ToString(); } private static string GetTab(string textTab, ulong count) { StringBuilder builder = new StringBuilder(); for (ulong I = 0; I < count; I++) builder.Append(textTab); return builder.ToString(); } } }