C# XML im/export
von king-crash- SNIPPET_DESC:
- Ein Objekt kann von und nach XML gewandelt werden.
- SNIPPET_CREATION_TIME:
- 23.08.2020 23:11:15
- SNIPPET_PRUNE_TIME:
- Unendlich
- SNIPPET_TEXT:
-
- using System;
- namespace xml
- {
- public static class XMLer
- {
- static readonly string strAttributeDataType = "datatype";
- static readonly string strAttributeName = "name";
- static readonly string strTypeNull = "null";
- static readonly string strTypePrimitive = "primitive";
- static readonly string strTypeArray = "array";
- static readonly string strTypeClass = "class";
- static class Raw
- {
- public static bool IsRawableType(Type type)
- {
- if (type.Equals(typeof(float)) ||
- type.Equals(typeof(double)) ||
- type.Equals(typeof(decimal)))
- {
- return true;
- }
- return false;
- }
- static bool IsXDigit(char c)
- {
- if ('0' <= c && c <= '9') return true;
- if ('a' <= c && c <= 'f') return true;
- if ('A' <= c && c <= 'F') return true;
- return false;
- }
- static byte[] hexStringToBytes(string str)
- {
- do
- {
- if (str.Length % 2 != 0)
- {
- break;
- }
- foreach (char c in str)
- {
- if (!IsXDigit(c))
- {
- break;
- }
- }
- byte[] ret = new byte[str.Length / 2];
- for (int i = 0; i < str.Length; i+=2)
- {
- string temp = str.Substring(i, 2);
- ret[i / 2] = byte.Parse(temp, System.Globalization.NumberStyles.HexNumber);
- }
- return ret;
- } while (false);
- throw new ArgumentException("Ungültiger Hex-String.");
- }
- public static Object FromString(string str, Type type)
- {
- Object ret;
- bool raw = false;
- if (str.StartsWith("R", StringComparison.Ordinal))
- {
- raw = true;
- str = str.Remove(0, 1);
- }
- if (type.Equals(typeof(float)))
- {
- if (raw)
- {
- ret = BitConverter.ToSingle(hexStringToBytes(str), 0);
- }
- else
- {
- ret = float.Parse(str);
- }
- }
- else if (type.Equals(typeof(double)))
- {
- if (raw)
- {
- ret = BitConverter.ToDouble(hexStringToBytes(str), 0);
- }
- else
- {
- ret = double.Parse(str);
- }
- }
- else if (type.Equals(typeof(decimal)))
- {
- if (raw)
- {
- string[] strings = str.Split(',');
- if (strings.Length != 4)
- {
- throw new Exception("Ungültiger Rawwert für decimal.");
- }
- ret = new decimal(new int[] { int.Parse(strings[0]), int.Parse(strings[1]), int.Parse(strings[2]), int.Parse(strings[3]) });
- }
- else
- {
- ret = decimal.Parse(str);
- }
- }
- else
- {
- throw new ArgumentException("Invalid Type \"" + type.FullName + "\" given.");
- }
- return ret;
- }
- public static string ToString(Object o)
- {
- string ret;
- Type type = o.GetType();
- if (type == typeof(float))
- {
- ret = "R" + BytesToString(BitConverter.GetBytes((float)o));
- }
- else if (type == typeof(double))
- {
- ret = "R" + BytesToString(BitConverter.GetBytes((double)o));
- }
- else if (type == typeof(decimal))
- {
- int[] ints = decimal.GetBits((decimal)o);
- ret = "R" + ints[0].ToString() + "," + ints[0].ToString() + "," + ints[0].ToString() + "," + ints[0].ToString();
- }
- else
- {
- throw new ArgumentException("Invalid Type \"" + o.GetType().FullName + "\" given.");
- }
- return ret;
- }
- static string BytesToString(byte[] bytes)
- {
- string ret = "";
- foreach (byte b in bytes)
- {
- ret += b.ToString("X2");
- }
- return ret;
- }
- }
- static System.Xml.XmlElement ObjectToXML(Object o, string name, System.Xml.XmlDocument xdoc)
- {
- Type type = o != null ? o.GetType() : null;
- string typename;
- if (o == null)
- {
- typename = "null";
- }
- else if (type.IsPrimitive)
- {
- typename = "primitive";
- }
- else if (type.IsArray)
- {
- typename = "array";
- }
- else if (type.IsClass)
- {
- typename = "class";
- }
- else
- {
- throw new Exception("Unbekannter Typ \"" + type.FullName + "\" für Variable \"" + name + "\".");
- }
- System.Xml.XmlElement xmlElement = xdoc.CreateElement(string.Empty, typename, string.Empty);
- xmlElement.SetAttribute(strAttributeName, name);
- if (o != null)
- {
- xmlElement.SetAttribute(strAttributeDataType, o.GetType().FullName);
- if (type.IsPrimitive || type.Equals(typeof(string)))
- {
- string str;
- if (type == typeof(float) ||
- type == typeof(double) ||
- type == typeof(decimal))
- {
- str = Raw.ToString(o);
- }
- else
- {
- str = o.ToString();
- }
- xmlElement.InnerText = str;
- }
- else if (type.IsArray)
- {
- int length = ((Array)o).Length;
- for(int i=0;i<length;i++)
- {
- xmlElement.AppendChild(ObjectToXML(((Array)o).GetValue(i), i.ToString(), xdoc));
- }
- }
- else if (type.IsClass)
- {
- foreach (System.Reflection.FieldInfo fieldInfo in o.GetType().GetFields())
- {
- xmlElement.AppendChild(ObjectToXML(fieldInfo.GetValue(o), fieldInfo.Name, xdoc));
- }
- }
- }
- return xmlElement;
- }
- public static void ToXMLFile(Object o, string filename)
- {
- System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
- xdoc.PreserveWhitespace = true;
- System.Xml.XmlDeclaration xmldecl;
- xmldecl = xdoc.CreateXmlDeclaration("1.0", "UTF-8", null);
- System.Xml.XmlElement root = xdoc.DocumentElement;
- xdoc.InsertBefore(xmldecl, root);
- xdoc.InsertAfter(ObjectToXML(o, "", xdoc), xmldecl);
- System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
- {
- Indent = true,
- IndentChars = "\t",
- NewLineChars = "\n",
- NewLineHandling = System.Xml.NewLineHandling.Replace
- };
- settings.Encoding = System.Text.Encoding.UTF8;
- System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
- System.IO.StreamWriter textWriter = new System.IO.StreamWriter(memoryStream, System.Text.Encoding.UTF8);
- using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(textWriter, settings))
- {
- xdoc.Save(writer);
- }
- using (System.IO.FileStream file = System.IO.File.Create(filename))
- {
- memoryStream.WriteTo(file);
- }
- }
- static string ReadXMLAttr(string attrName, System.Xml.XmlNode xNode)
- {
- System.Xml.XmlAttributeCollection c = xNode.Attributes;
- System.Xml.XmlAttribute attr = xNode.Attributes[attrName];
- if (attr == null)
- {
- throw new Exception("Fehlendes Attribut \"" + attrName + "\".");
- }
- return attr.Value;
- }
- static bool XmlNodeHasRealChildNodes(System.Xml.XmlNode xNode)
- {
- foreach (System.Xml.XmlNode child in xNode.ChildNodes)
- {
- if (child.NodeType != System.Xml.XmlNodeType.Text)
- {
- return true;
- }
- }
- return false;
- }
- static Object ObjectFromXML(Object parent, System.Xml.XmlNode xNode)
- {
- Object ret;
- if (xNode.LocalName == strTypeNull)
- {
- ret = null;
- }
- else
- {
- string typeName = ReadXMLAttr(strAttributeDataType, xNode);
- Type type = Type.GetType(typeName);
- if (xNode.LocalName == strTypePrimitive || type.Equals(typeof(string)))
- {
- if (XmlNodeHasRealChildNodes(xNode))
- {
- throw new Exception("\"" + strTypePrimitive + "\" darf keine Unterelemente haben.");
- }
- if (Raw.IsRawableType(type))
- {
- ret = Raw.FromString(xNode.InnerText, type);
- }
- else
- {
- ret = Convert.ChangeType(xNode.InnerText, type);
- }
- }
- else if (xNode.LocalName == strTypeClass)
- {
- ret = Activator.CreateInstance(type);
- }
- else if (xNode.LocalName == strTypeArray)
- {
- ret = Array.CreateInstance(type.GetElementType(), xNode.ChildNodes.Count);
- }
- else
- {
- throw new Exception("Unbekanntes Element \"" + xNode.LocalName + "\".");
- }
- if ((xNode.LocalName == strTypeClass && type != typeof(string)) ||
- xNode.LocalName == strTypeArray)
- {
- foreach (System.Xml.XmlNode xmlNode in xNode.ChildNodes)
- {
- ObjectFromXML(ret, xmlNode);
- }
- }
- }
- if (parent != null)
- {
- string name = ReadXMLAttr(strAttributeName, xNode);
- if (parent.GetType().IsArray)
- {
- ((Array)parent).SetValue(ret, Convert.ToInt32(name));
- }
- else
- {
- parent.GetType().GetField(name).SetValue(parent, ret);
- }
- }
- return ret;
- }
- /// <summary>
- /// Erstellt ein Objekt samt Unterobjekten aus einer XML-Datei
- /// </summary>
- /// <returns>Das erstellte Objekt.</returns>
- /// <param name="xmlName">Name der XML-Datei.</param>
- /// <param name="refType">Wenn ungleich null, muss der Objekttyp mit diesem übereinstimmen.</param>
- public static Object FromXMLFile(string xmlName, Type refType = null)
- {
- System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
- xDoc.Load(xmlName);
- if (xDoc.FirstChild != null && xDoc.FirstChild.NodeType == System.Xml.XmlNodeType.XmlDeclaration)
- {
- xDoc.RemoveChild(xDoc.FirstChild);
- }
- if (xDoc.ChildNodes.Count != 1)
- {
- throw new Exception("Es muss genau ein oberstes XML-Element geben.");
- }
- Object ret = ObjectFromXML(null, xDoc.FirstChild);
- if (refType != null && !ret.GetType().Equals(refType))
- {
- throw new Exception("Ungültiger Objekttyp für Basisobjekt.");
- }
- return ret;
- }
- }
- }
Quellcode
Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN