using System.Linq;
using System.Text;
using Cobilas.Collections;
namespace System.Xml {
///
/// Extension that adds reading and writing functions for XML.
///
public static class CB_XML_Extension {
#region WriterXML
///
/// Uses an to write to the xml document.
///
public static void WriterXMLIRW(this XmlWriter writer, XMLIRWElement element) {
writer.WriteStartDocument();
if (writer.Settings.Indent)
writer.WriteWhitespace(writer.Settings.NewLineChars);
Xmlwriter(element, writer);
writer.WriteEndDocument();
}
private static void Xmlwriter(XMLIRWElement element, XmlWriter writer, ulong level = 0UL) {
if (element.IsEmpty) return;
foreach (XMLIRW item in element) {
if (item is null)
throw new ArgumentNullException($"The element inside \"{element.Name}\" is null!");
if (item is XMLIRWProcessingInstruction pi) {
if (writer.Settings.Indent)
writer.WriteWhitespace(IndentLevel(level, writer.Settings.IndentChars));
if (pi.IsAttributeList) {
StringBuilder builder = new StringBuilder();
foreach (XMLIRWAttribute attri in pi)
builder.AppendFormat("{0}=\"{1}\" ", attri.Name, (string)attri.Text);
writer.WriteProcessingInstruction(pi.Name, builder.ToString().TrimEnd());
} else {
writer.WriteProcessingInstruction(pi.Name, (string)pi.Text);
}
if (writer.Settings.Indent)
writer.WriteWhitespace(writer.Settings.NewLineChars);
} else if (item is XMLIRWComment cm) {
if (writer.Settings.Indent)
writer.WriteWhitespace(IndentLevel(level, writer.Settings.IndentChars));
writer.WriteComment((string)cm.Text);
if (writer.Settings.Indent)
writer.WriteWhitespace(writer.Settings.NewLineChars);
} else if (item is XMLIRWCDATA cd) {
if (writer.Settings.Indent)
writer.WriteWhitespace(IndentLevel(level, writer.Settings.IndentChars));
writer.WriteCData((string)cd.Text);
if (writer.Settings.Indent)
writer.WriteWhitespace(writer.Settings.NewLineChars);
} else if (item is XMLIRWDocType doc) {
if (writer.Settings.Indent)
writer.WriteWhitespace(IndentLevel(level, writer.Settings.IndentChars));
writer.WriteDocType(doc.Name, (string)doc.PudID, (string)doc.SysID, (string)doc.SubSet);
if (writer.Settings.Indent)
writer.WriteWhitespace(writer.Settings.NewLineChars);
} else if (item is XMLIRWElement ele) {
if (writer.Settings.Indent)
writer.WriteWhitespace(IndentLevel(level, writer.Settings.IndentChars));
writer.WriteStartElement(ele.Name);
if (!ele.NoAttributes)
foreach (XMLIRWAttribute attris in ele.Attributes.Cast())
writer.WriteAttributeString(attris.Name, (string)attris.Text);
bool noText = false;
if (!ele.ValueIsEmpty) {
noText = true;
writer.WriteString((string)ele.Text);
if (writer.Settings.Indent && !ele.NoElements)
writer.WriteWhitespace(writer.Settings.NewLineChars);
}
if (!ele.NoElements) {
if (writer.Settings.Indent && !noText)
writer.WriteWhitespace(writer.Settings.NewLineChars);
Xmlwriter(ele, writer, level + 1);
}
if (writer.Settings.Indent && !ele.NoElements)
writer.WriteWhitespace(IndentLevel(level, writer.Settings.IndentChars));
writer.WriteEndElement();
if (writer.Settings.Indent)
writer.WriteWhitespace(writer.Settings.NewLineChars);
}
}
}
private static string IndentLevel(ulong level, string text) {
StringBuilder builder = new StringBuilder();
for (ulong I = 0; I < level; I++)
builder.Append(text);
return builder.ToString();
}
#endregion
#region ReadXML
///
/// Reads an XML document and returns an .
///
public static XMLIRWElement ReadXMLIRW(this XmlReader reader) {
XMLIRWElement element = new XMLIRWElement("Root");
XmlDocument document = new XmlDocument();
document.Load(reader);
SetXMLIRWElement(document, element);
return element;
}
private static void SetXMLIRWElement(XmlNode document, XMLIRWElement root) {
foreach (XmlNode node in document) {
if (node is XmlDeclaration dec)
root.Add(new XMLIRWDeclaration(dec.Version, dec.Encoding, dec.Standalone));
else if (node is XmlDocumentType doc)
root.Add(new XMLIRWDocType(node.LocalName, doc.PublicId, doc.SystemId, doc.InternalSubset));
else if (node is XmlCDataSection cd)
root.Add(new XMLIRWCDATA(cd.Value));
else if (node is XmlProcessingInstruction pi) {
if (!ArrayManipulation.EmpytArray(pi.Attributes)) {
XMLIRWAttribute[] attributes = new XMLIRWAttribute[pi.Attributes.Count];
for (int I = 0; I < pi.Attributes.Count; I++) {
XmlAttribute attribute = pi.Attributes[I];
attributes[I] = new XMLIRWAttribute(attribute.LocalName, attribute.InnerText);
}
root.Add(new XMLIRWProcessingInstruction(pi.Target, attributes));
} else root.Add(new XMLIRWProcessingInstruction(pi.Target, pi.Data));
} else if (node is XmlComment cm)
root.Add(new XMLIRWComment(cm.InnerText));
else if (node is XmlText text) {
root.Add(new XMLIRWText(text.Data));
} else if (node is XmlElement ele) {
XMLIRWElement element = new XMLIRWElement(ele.LocalName);
if (ele.Attributes.Count != 0)
for (int I = 0; I < ele.Attributes.Count; I++) {
XmlAttribute attribute = ele.Attributes[I];
element.Add(new XMLIRWAttribute(attribute.LocalName, attribute.InnerText));
}
if (ele.ChildNodes.Count != 0) {
SetXMLIRWElement(ele, element);
}
root.Add(element);
}
}
}
#endregion
}
}