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();
}
}
}