Laden...

WP7: Nach XML Node hinzufügen - Doppelte Struktur

Erstellt von elTorito vor 10 Jahren Letzter Beitrag vor 10 Jahren 1.250 Views
elTorito Themenstarter:in
177 Beiträge seit 2009
vor 10 Jahren
WP7: Nach XML Node hinzufügen - Doppelte Struktur

Hi,

ich versuch gerade mal den Einstieg in Windows Phone App Programmierung 😁
Da ich in meiner Win8 VM keine Hardware Virtualisierung habe, und den Emulator nicht ans laufen bekomme (kein SLAT dingsda) versuche ich nun erstmal auf Windows 7 eine App für WP 7.8 zu machen.

Ok. Nach Starten der App prüfe ich ob die Datei Races.xml im IsolatedStorage vorliegt, wenn nein, dann erzeuge ich eine solche Datei:

XmlSerializer serializer = new XmlSerializer(typeof(Races));
  using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
  {
   serializer.Serialize(xmlWriter, GetRaces());
   xmlWriter.Close();
  }

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <races>
    <race>
      <raceId>1</raceId>
      <raceName>Rennen 1</raceName>
      <racePicture>/Images/User/image.png</racePicture>
      <raceInfo>Beschreibung</raceInfo>
    </race>
     <race>...</race>
     ...
  </races>
</root>

Anschliessend lese ich die Datei aus und binde die Daten an eine ListBox:


                            XmlSerializer serializer = new XmlSerializer(typeof(Races));
                            Races races = (Races)serializer.Deserialize(str);
                            racesList.ItemsSource = races.Collection;

Nun möchte ich ein weitere Objekt Race in diese XML Datei hinzufügen:


XDocument xDoc = XDocument.Load(MyIsoStorageFileStream);
                    var newRace = new XElement("race",
                                        new XElement("raceId", txtRaceId.Text),
                                        new XElement("racenName", txtRaceName.Text),
                                        new XElement("raceInfo", txtRaceInfo.Text)
                                        );
                    xDoc.Descendants("races").FirstOrDefault().Add(new XElement(newRace));
                    xDoc.Save(MyIsoStorageFileStream);

Damit bekomme ich in der XML Datei eine doppelte Struktur, an dem was schon vorhanden war, wird das gleiche plus der neue Node noch angehängt:


<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <races>
    <race>
      <raceId>1</raceId>
      <raceName>Rennen 1</raceName>
      <racePicture>/Images/User/image.png</racePicture>
      <raceInfo>Beschreibung</raceInfo>
    </race>
  </races>
</root><root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <races>
    <race>
      <raceId>1</raceId>
      <raceName>Rennen 1</raceName>
      <racePicture>/Images/User/image.png</racePicture>
      <raceInfo>Beschreibung</raceInfo>
    </race>
    <race>
      <raceId>2</raceId>
      <raceName>Bambini Banana</raceName>
      <racePicture>/Images/testimage.png</racePicture>
      <raceInfo>Test Info </raceInfo>
    </race>
  </races>
</root>

Hab mir dann gedacht : ok, muss das ganze ja evtl. Serialisieren, mir also meine Liste geholt und das neue Element dran gehängt und dann nochmal alles abgeschickt, aber auch damit erhalte ich wie oben ein doppelten Root Tree:


                   Races loadedRaces = new Races();
                    XmlSerializer serializer = new XmlSerializer(typeof(Races));
                    Races races = (Races)serializer.Deserialize(isoStream);
                    loadedRaces.Collection =  races.Collection;

                    Race r = new Race();
                    r.raceId = "1";
                    r.raceName = "Neuer Rennen Name fistro";
                    r.raceInfo = "Neue beschreibung für fistro";

                    loadedRaces.Collection.Add(r);

                    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
                    xmlWriterSettings.Indent = true;
                    XmlSerializer xs = new XmlSerializer(typeof(Races),"race");
                    using (XmlWriter xmlWriter = XmlWriter.Create(isoStream, xmlWriterSettings))
                    {
                        serializer.Serialize(xmlWriter, loadedRaces);
                        xmlWriter.Close();
                    }

Hmm. Wo ist mein Denkfehler?
🤔

Danke

W
113 Beiträge seit 2006
vor 10 Jahren

Hallo elTorito,

kann es sein dass du den Konstruktor des IsolatedStorageFilesStream mit FileMode=Append aufrufst?

gruß,
xan

elTorito Themenstarter:in
177 Beiträge seit 2009
vor 10 Jahren

Hi xan,

Ne, ich hab Open und OpenOrCreate probiert:


using (IsolatedStorageFileStream isoStream = myIsolatedStorage.OpenFile("Races.xml", FileMode.Open, FileAccess.ReadWrite))

W
113 Beiträge seit 2006
vor 10 Jahren

Hallo elTorito,

nimmst du denselben Stream zum Lesen und zum Schreiben her?

Falls ja wird beim Lesen des Inhalts die Position im Stream an dessen Ende gesetzt und beim Schreiben von der Position weitergeschrieben.

Setz mal die Position des Streams auf den Start bevor du in den Stream schreibst.

Ist zwar nicht so gut, wenn der neue Inhalt kürzer sein sollte als der alte, aber zum Testen sollte es kein Problem sein.

Meiner Meinung nach wäre es am sinnvollsten das Laden und Speichern mit 2 seperaten Streams durchzuführen, wobei du dann den Stream zum Speichern mit Create erzeugen kannst.

Gruß,
Xan

elTorito Themenstarter:in
177 Beiträge seit 2009
vor 10 Jahren

Hallo Xan,

ja ich hatte/habe den gleichen Stream benutzt. 😁

Ich habe jetzt 2 Streams, im ersten wird die XML Datei geladen und Deserialisiert so das ich die enthaltenen Objekte bekomme.

Dann füge ich mein neues Objekt hinzu. Und speichere den das ganze einfach neu im Stream mit FileMode.Create.

Das scheint nun so zu funktionieren.

Vielen Dank!

Darf ich vielleicht auch noch eine Doofe Anfänger Frage stellen. 8o
So wie das jetzt ist, wird die XML Datei eingelesen, ich häng mein neues Objekt dran und schicke meine ObjektListe wieder in die Datei. Das was ich zuerst vor hatte, die Datei öffnen, und nur den neuen Knoten hinzufügen, hat wahrscheinlich kein Vorteil gegenüber alles nochmal speichern?

W
113 Beiträge seit 2006
vor 10 Jahren

Hallo elTorito,

also Vorteil hat es wenn überhaupt nur einen Performance Vorteil. Lesbarer und auch wartbarer ist es auf jeden Fall, wenn du alles über die Serialisierung machst.

Vor allem wenn sich deine Klasse ändert die du serialisierst, dann musst du an jeder Stelle wo du manuell die XML Datei veränderst Anpassungen machen.

mfg,
xan

elTorito Themenstarter:in
177 Beiträge seit 2009
vor 10 Jahren

Vor allem wenn sich deine Klasse ändert die du serialisierst, dann musst du an jeder Stelle wo du manuell die XML Datei veränderst Anpassungen machen.

Ja, das macht Sinn.

Vielen Dank nochmal für deine Hilfe!

Peter