NoPaste

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:
  1. using System;
  2. namespace xml
  3. {
  4.         public static class XMLer
  5.         {
  6.                 static readonly string strAttributeDataType = "datatype";
  7.                 static readonly string strAttributeName = "name";
  8.                 static readonly string strTypeNull = "null";
  9.                 static readonly string strTypePrimitive = "primitive";
  10.                 static readonly string strTypeArray = "array";
  11.                 static readonly string strTypeClass = "class";
  12.  
  13.                 static class Raw
  14.                 {
  15.                         public static bool IsRawableType(Type type)
  16.                         {
  17.                                 if (type.Equals(typeof(float)) ||
  18.                                         type.Equals(typeof(double)) ||
  19.                                         type.Equals(typeof(decimal)))
  20.                                 {
  21.                                         return true;
  22.                                 }
  23.                                 return false;
  24.                         }
  25.  
  26.                         static bool IsXDigit(char c)
  27.                         {
  28.                                 if ('0' <= c && c <= '9') return true;
  29.                                 if ('a' <= c && c <= 'f') return true;
  30.                                 if ('A' <= c && c <= 'F') return true;
  31.                                 return false;
  32.                         }
  33.  
  34.                         static byte[] hexStringToBytes(string str)
  35.                         {
  36.                                 do
  37.                                 {
  38.                                         if (str.Length % 2 != 0)
  39.                                         {
  40.                                                 break;
  41.                                         }
  42.                                         foreach (char c in str)
  43.                                         {
  44.                                                 if (!IsXDigit(c))
  45.                                                 {
  46.                                                         break;
  47.                                                 }
  48.                                         }
  49.                                         byte[] ret = new byte[str.Length / 2];
  50.                                         for (int i = 0; i < str.Length; i+=2)
  51.                                         {
  52.                                                 string temp = str.Substring(i, 2);
  53.                                                 ret[i / 2] = byte.Parse(temp, System.Globalization.NumberStyles.HexNumber);
  54.                                         }
  55.                                         return ret;
  56.                                 } while (false);
  57.                                 throw new ArgumentException("Ungültiger Hex-String.");
  58.                         }
  59.  
  60.                         public static Object FromString(string str, Type type)
  61.                         {
  62.                                 Object ret;
  63.                                 bool raw = false;
  64.                                 if (str.StartsWith("R", StringComparison.Ordinal))
  65.                                 {
  66.                                         raw = true;
  67.                                         str = str.Remove(0, 1);
  68.                                 }
  69.                                 if (type.Equals(typeof(float)))
  70.                                 {
  71.                                         if (raw)
  72.                                         {
  73.                                                 ret = BitConverter.ToSingle(hexStringToBytes(str), 0);
  74.                                         }
  75.                                         else
  76.                                         {
  77.                                                 ret = float.Parse(str);
  78.                                         }
  79.                                 }
  80.                                 else if (type.Equals(typeof(double)))
  81.                                 {
  82.                                         if (raw)
  83.                                         {
  84.                                                 ret = BitConverter.ToDouble(hexStringToBytes(str), 0);
  85.                                         }
  86.                                         else
  87.                                         {
  88.                                                 ret = double.Parse(str);
  89.                                         }
  90.                                 }
  91.                                 else if (type.Equals(typeof(decimal)))
  92.                                 {
  93.                                         if (raw)
  94.                                         {
  95.                                                 string[] strings = str.Split(',');
  96.                                                 if (strings.Length != 4)
  97.                                                 {
  98.                                                         throw new Exception("Ungültiger Rawwert für decimal.");
  99.                                                 }
  100.                                                 ret = new decimal(new int[] { int.Parse(strings[0]), int.Parse(strings[1]), int.Parse(strings[2]), int.Parse(strings[3]) });
  101.                                         }
  102.                                         else
  103.                                         {
  104.                                                 ret = decimal.Parse(str);
  105.                                         }
  106.                                 }
  107.                                 else
  108.                                 {
  109.                                         throw new ArgumentException("Invalid Type \"" + type.FullName + "\" given.");
  110.                                 }
  111.                                 return ret;
  112.                         }
  113.  
  114.                         public static string ToString(Object o)
  115.                         {
  116.                                 string ret;
  117.  
  118.                                 Type type = o.GetType();
  119.                                 if (type == typeof(float))
  120.                                 {
  121.                                         ret = "R" + BytesToString(BitConverter.GetBytes((float)o));
  122.                                 }
  123.                                 else if (type == typeof(double))
  124.                                 {
  125.                                         ret = "R" + BytesToString(BitConverter.GetBytes((double)o));
  126.                                 }
  127.                                 else if (type == typeof(decimal))
  128.                                 {
  129.                                         int[] ints = decimal.GetBits((decimal)o);
  130.                                         ret = "R" + ints[0].ToString() + "," + ints[0].ToString() + "," + ints[0].ToString() + "," + ints[0].ToString();
  131.                                 }
  132.                                 else
  133.                                 {
  134.                                         throw new ArgumentException("Invalid Type \"" + o.GetType().FullName + "\" given.");
  135.                                 }
  136.                                 return ret;
  137.                         }
  138.                         static string BytesToString(byte[] bytes)
  139.                         {
  140.                                 string ret = "";
  141.                                 foreach (byte b in bytes)
  142.                                 {
  143.                                         ret += b.ToString("X2");
  144.                                 }
  145.                                 return ret;
  146.                         }
  147.                 }
  148.  
  149.                         static System.Xml.XmlElement ObjectToXML(Object o, string name, System.Xml.XmlDocument xdoc)
  150.                 {
  151.                         Type type = o != null ? o.GetType() : null;
  152.                         string typename;
  153.                         if (o == null)
  154.                         {
  155.                                 typename = "null";
  156.                         }
  157.                         else if (type.IsPrimitive)
  158.                         {
  159.                                 typename = "primitive";
  160.                         }
  161.                         else if (type.IsArray)
  162.                         {
  163.                                 typename = "array";
  164.                         }
  165.                         else if (type.IsClass)
  166.                         {
  167.                                 typename = "class";
  168.                         }
  169.                         else
  170.                         {
  171.                                 throw new Exception("Unbekannter Typ \"" + type.FullName + "\" für Variable \"" + name + "\".");
  172.                         }
  173.                         System.Xml.XmlElement xmlElement = xdoc.CreateElement(string.Empty, typename, string.Empty);
  174.                         xmlElement.SetAttribute(strAttributeName, name);
  175.                         if (o != null)
  176.                         {
  177.                                 xmlElement.SetAttribute(strAttributeDataType, o.GetType().FullName);
  178.  
  179.                                 if (type.IsPrimitive || type.Equals(typeof(string)))
  180.                                 {
  181.                                         string str;
  182.                                         if (type == typeof(float) ||
  183.                                                 type == typeof(double) ||
  184.                                                 type == typeof(decimal))
  185.                                         {
  186.                                                 str = Raw.ToString(o);
  187.                                         }
  188.                                         else
  189.                                         {
  190.                                                 str = o.ToString();
  191.                                         }
  192.                                         xmlElement.InnerText = str;
  193.                                 }
  194.                                 else if (type.IsArray)
  195.                                 {
  196.                                         int length = ((Array)o).Length;
  197.                                         for(int i=0;i<length;i++)
  198.                                         {
  199.                                                 xmlElement.AppendChild(ObjectToXML(((Array)o).GetValue(i), i.ToString(), xdoc));
  200.                                         }
  201.                                 }
  202.                                 else if (type.IsClass)
  203.                                 {
  204.                                         foreach (System.Reflection.FieldInfo fieldInfo in o.GetType().GetFields())
  205.                                         {
  206.                                                 xmlElement.AppendChild(ObjectToXML(fieldInfo.GetValue(o), fieldInfo.Name, xdoc));
  207.                                         }
  208.                                 }
  209.                         }
  210.                         return xmlElement;
  211.                 }
  212.  
  213.                 public static void ToXMLFile(Object o, string filename)
  214.                 {
  215.                         System.Xml.XmlDocument xdoc = new System.Xml.XmlDocument();
  216.                         xdoc.PreserveWhitespace = true;
  217.                         System.Xml.XmlDeclaration xmldecl;
  218.                         xmldecl = xdoc.CreateXmlDeclaration("1.0", "UTF-8", null);
  219.                         System.Xml.XmlElement root = xdoc.DocumentElement;
  220.                         xdoc.InsertBefore(xmldecl, root);
  221.                         xdoc.InsertAfter(ObjectToXML(o, "", xdoc), xmldecl);
  222.  
  223.                         System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
  224.                         {
  225.                                 Indent = true,
  226.                                 IndentChars = "\t",
  227.                                 NewLineChars = "\n",
  228.                                 NewLineHandling = System.Xml.NewLineHandling.Replace
  229.                         };
  230.                         settings.Encoding = System.Text.Encoding.UTF8;
  231.  
  232.                         System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
  233.                         System.IO.StreamWriter textWriter = new System.IO.StreamWriter(memoryStream, System.Text.Encoding.UTF8);
  234.                         using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create(textWriter, settings))
  235.                         {
  236.                                 xdoc.Save(writer);
  237.                         }
  238.                         using (System.IO.FileStream file = System.IO.File.Create(filename))
  239.                         {
  240.                                 memoryStream.WriteTo(file);
  241.                         }
  242.                 }
  243.  
  244.                 static string ReadXMLAttr(string attrName, System.Xml.XmlNode xNode)
  245.                 {
  246.                         System.Xml.XmlAttributeCollection c = xNode.Attributes;
  247.                         System.Xml.XmlAttribute attr = xNode.Attributes[attrName];
  248.                         if (attr == null)
  249.                         {
  250.                                 throw new Exception("Fehlendes Attribut \"" + attrName + "\".");
  251.                         }
  252.                         return attr.Value;
  253.                 }
  254.  
  255.                 static bool XmlNodeHasRealChildNodes(System.Xml.XmlNode xNode)
  256.                 {
  257.                         foreach (System.Xml.XmlNode child in xNode.ChildNodes)
  258.                         {
  259.                                 if (child.NodeType != System.Xml.XmlNodeType.Text)
  260.                                 {
  261.                                         return true;
  262.                                 }
  263.                         }
  264.                         return false;
  265.                 }
  266.  
  267.                 static Object ObjectFromXML(Object parent, System.Xml.XmlNode xNode)
  268.                 {
  269.                         Object ret;
  270.                         if (xNode.LocalName == strTypeNull)
  271.                         {
  272.                                 ret = null;
  273.                         }
  274.                         else
  275.                         {
  276.                                 string typeName = ReadXMLAttr(strAttributeDataType, xNode);
  277.                                 Type type = Type.GetType(typeName);
  278.                                 if (xNode.LocalName == strTypePrimitive || type.Equals(typeof(string)))
  279.                                 {
  280.                                         if (XmlNodeHasRealChildNodes(xNode))
  281.                                         {
  282.                                                 throw new Exception("\"" + strTypePrimitive + "\" darf keine Unterelemente haben.");
  283.                                         }
  284.                                         if (Raw.IsRawableType(type))
  285.                                         {
  286.                                                 ret = Raw.FromString(xNode.InnerText, type);
  287.                                         }
  288.                                         else
  289.                                         {
  290.                                                 ret = Convert.ChangeType(xNode.InnerText, type);
  291.                                         }
  292.                                 }
  293.                                 else if (xNode.LocalName == strTypeClass)
  294.                                 {
  295.                                         ret = Activator.CreateInstance(type);
  296.                                 }
  297.                                 else if (xNode.LocalName == strTypeArray)
  298.                                 {
  299.                                         ret = Array.CreateInstance(type.GetElementType(), xNode.ChildNodes.Count);
  300.                                 }
  301.                                 else
  302.                                 {
  303.                                         throw new Exception("Unbekanntes Element \"" + xNode.LocalName + "\".");
  304.                                 }
  305.  
  306.                                 if ((xNode.LocalName == strTypeClass && type != typeof(string)) ||
  307.                                         xNode.LocalName == strTypeArray)
  308.                                 {
  309.                                         foreach (System.Xml.XmlNode xmlNode in xNode.ChildNodes)
  310.                                         {
  311.                                                 ObjectFromXML(ret, xmlNode);
  312.                                         }
  313.                                 }
  314.                         }
  315.  
  316.                         if (parent != null)
  317.                         {
  318.                                 string name = ReadXMLAttr(strAttributeName, xNode);
  319.                                 if (parent.GetType().IsArray)
  320.                                 {
  321.                                         ((Array)parent).SetValue(ret, Convert.ToInt32(name));
  322.                                 }
  323.                                 else
  324.                                 {
  325.                                         parent.GetType().GetField(name).SetValue(parent, ret);
  326.                                 }
  327.                         }
  328.                         return ret;
  329.                 }
  330.  
  331.                 /// <summary>
  332.                 /// Erstellt ein Objekt samt Unterobjekten aus einer XML-Datei
  333.                 /// </summary>
  334.                 /// <returns>Das erstellte Objekt.</returns>
  335.                 /// <param name="xmlName">Name der XML-Datei.</param>
  336.                 /// <param name="refType">Wenn ungleich null, muss der Objekttyp mit diesem übereinstimmen.</param>
  337.                 public static Object FromXMLFile(string xmlName, Type refType = null)
  338.                 {
  339.                         System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument();
  340.                         xDoc.Load(xmlName);
  341.                         if (xDoc.FirstChild != null && xDoc.FirstChild.NodeType == System.Xml.XmlNodeType.XmlDeclaration)
  342.                         {
  343.                                 xDoc.RemoveChild(xDoc.FirstChild);
  344.                         }
  345.                         if (xDoc.ChildNodes.Count != 1)
  346.                         {
  347.                                 throw new Exception("Es muss genau ein oberstes XML-Element geben.");
  348.                         }
  349.  
  350.                         Object ret = ObjectFromXML(null, xDoc.FirstChild);
  351.                         if (refType != null && !ret.GetType().Equals(refType))
  352.                         {
  353.                                 throw new Exception("Ungültiger Objekttyp für Basisobjekt.");
  354.                         }
  355.                         return ret;
  356.                 }
  357.         }
  358. }

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN