Laden...

InvalidOperationException beim Mappen einer XML Datei auf eine C# Klasse

Erstellt von Bradley vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.457 Views
B
Bradley Themenstarter:in
153 Beiträge seit 2014
vor 7 Jahren
InvalidOperationException beim Mappen einer XML Datei auf eine C# Klasse

Hallo Leute,

ich versuche mich gerade daran eine XML Datei auf eine Klasse zu Mappen.
Hintergrund ist, das ich versuche die Daten in meinem Spiel besser zu Strukturieren.

Ich verwende folgenden Code:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Xml.Serialization;

namespace SpaceOperaMapping
{
    class Program
    {

        static void Main(string[] args)
        {
            // Läd die XML 
            var doc = XDocument.Load("Config2.xml");

            // Definiert die MappingAttribute
            var serializer = new XmlSerializer(typeof(Config));

            // Hier wird ein Root aus dem Doc angegeben 
            var reader = doc.Root.CreateReader();
                
            var temp = (Config)serializer.Deserialize(reader);

            Console.WriteLine(temp.ScreenWidth.ToString());
            Console.WriteLine(temp.ScreenHigh.ToString());

            Console.Read();
        }
    }


    [XmlRoot(ElementName = "Config")]
    public class Config
    {
        [XmlElement(ElementName = "High")]
        public int ScreenWidth { get; set; }

        [XmlElement(ElementName = "Width")]
        public int ScreenHigh { get; set; }


        public Config()
        {

        }
    }
}

Die XML Datei sieht so aus:


<?xml version="1.0" encoding="utf-8" ?>
<Config>
      <High h ="800"/>
      <Width w ="1280"/>
</Config>

Beim compilieren bekomme ich immer folgenden Fehler:> Fehlermeldung:

Ein Ausnahmefehler des Typs "System.InvalidOperationException" ist in System.Xml.dll aufgetreten.
Zusätzliche Informationen: Fehler im XML-Dokument (0,0).

Kann mir jemand bei meinem Denkfehler helfen?

[Space Opera Blog](http://bradley-software.blogspot.com/)
[Space Opera Forum](http://forum.bradley-labs.de/)
849 Beiträge seit 2006
vor 7 Jahren

Hallo,

machs mal andersrum. Erstelle ein Object vom Typ Config uns serialisier das.

Ich vermute das Xml würde dann etwa So aussehen:


<?xml version="1.0" encoding="utf-8" ?>
<Config>
      <High>800</High>
      <Width>1280</Width>
</Config>

Wenn Du Die Chance hast, stell dein Spiel Xml so um. Anders kommst Du an dieser Stelle wohl nur mit einer sehr komischen Object Struktur (Klasse High, Property h) oder dem Interface IXmlSerializable weiter.

edit: Jetzt wo ich deinen Code nochmal anschaue.. XDocument.Root.CreateReader wird dem XmlSerializer auch nicht das ganze Document geben. Vermutlich nur die ChildNodes von Config. Damit kann der XmlSerializer nichts anfangen. Der brauch das ganze xml.

3.003 Beiträge seit 2006
vor 7 Jahren

Wenn du das XML hast, und eine Klasse dazu brauchst: http://xmltocsharp.azurewebsites.net/

Code nach Bedarf weiter anpassen.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

B
Bradley Themenstarter:in
153 Beiträge seit 2014
vor 7 Jahren

Erstmal danke für die Hilfe, in der zwischen Zeit komme ich mit XML Serialisation ganz gut klar.

Ich möchte das Konzept jetzt wieder verwenden, allerdings im anderen Kontext, nämlich um die Wert der Tilemap zu speichern.

Die Tilemap ist ein 2-Dimensionales Array. Hier mal der Code eines Vereinfachten Prototypen:


    class Program
    {
        MapField[,] arraytest = new MapField[2,2];

        static void Main(string[] args)
        {
            Program obj = new Program();

            Speichern(obj);

            Laden();

        }

        private static void Laden()
        {
            List<MapField> list = new List<MapField>();

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(MapField));
            StreamReader sr = new StreamReader(@"test.xml");


            list.Add((MapField)xmlSerializer.Deserialize(sr));

            sr.Close();
        }

        private static void Speichern(Program obj)
        {
            for (int x = 0; x < 2; x++)
            {
                for (int y = 0; y < 2; y++)
                {
                    obj.arraytest[x, y] = new MapField();

                    obj.arraytest[x, y].Type = 1;
                    obj.arraytest[x, y].Visibile = false;
                    obj.arraytest[x, y].X = x;
                    obj.arraytest[x, y].Y = y;


                }
            }


            XmlSerializer xmlser = new XmlSerializer(typeof(MapField));
            StreamWriter sw = new StreamWriter("test.xml");

            foreach (var item in obj.arraytest)
            {
                xmlser.Serialize(sw, item);

            }
            sw.Close();
         }
    }

    [XmlRoot(ElementName = "MapField")]
    public class MapField
    {
        [XmlElement(ElementName = "X")]
        public int X { get; set; }
        [XmlElement(ElementName = "Y")]
        public int Y { get; set; }

        [XmlElement(ElementName = "Type")]
        public int Type { get; set; }
        [XmlElement(ElementName = "Visibile")]
        public bool Visibile { get; set; }
    }

Das schreiben der Daten in die XML geht wunderbar:

<?xml version="1.0" encoding="utf-8"?>
<MapField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <X>0</X>
  <Y>0</Y>
  <Type>1</Type>
  <Visibile>false</Visibile>
</MapField><?xml version="1.0" encoding="utf-8"?>
<MapField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <X>0</X>
  <Y>1</Y>
  <Type>1</Type>
  <Visibile>false</Visibile>
</MapField><?xml version="1.0" encoding="utf-8"?>
<MapField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <X>1</X>
  <Y>0</Y>
  <Type>1</Type>
  <Visibile>false</Visibile>
</MapField><?xml version="1.0" encoding="utf-8"?>
<MapField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <X>1</X>
  <Y>1</Y>
  <Type>1</Type>
  <Visibile>false</Visibile>
</MapField>

Jetzt will ich das ganze wieder laden.
Da die Serialisation von selbst keine Arrays unterstützen, war mein letzter Gedanke der, das ich alles zuerst in eine Liste Packe und von dort aus wieder ein neues Array befüllen.

Leider scheitere ich daran.
Jemand eine Idee wie ich das lösen kann?

[Space Opera Blog](http://bradley-software.blogspot.com/)
[Space Opera Forum](http://forum.bradley-labs.de/)
5.299 Beiträge seit 2008
vor 7 Jahren

serialisiere doch das ganze Array - nicht jedes MapField einzeln

var xmlser = new XmlSerializer(typeof(MapField[]));
//...

Der frühe Apfel fängt den Wurm.