Daten aus ListBox in XML Datei schreiben



  • Hallo zusammen,

    bei meinem Code wir nur der erste Knoten "eintraege" angezeigt - was mache ich falsch? Hat jemand einen Tipp für mich?

    private: System::Void buttonSpeichern_Click(System::Object^  sender, System::EventArgs^  e) {
    
    				 //eine Instanz anlegen
    
    				 XmlWriter ^xmlDatei = XmlWriter::Create("C:\\ILSxml\\Datei.xml");
    
    				 //die Deklaration schreiben
    
    				 xmlDatei->WriteStartDocument();
    
    				  // Die Wurzel schreiben
    				 xmlDatei->WriteStartElement("eintraege");
    
    				  for (Int32 i = 0; i < listBox1->SelectedItems->Count; i++){
    
    					  			 // den Knoten eintrag erzeugen
    
    					 xmlDatei->WriteElementString("ausgabe", listBox1->SelectedItems->ToString());
    
    					 //Knoten abschließen
    
    					 xmlDatei->WriteEndElement();
    
    				 }
    
    				//den Eintrag und die Datei schließen
    
    					 xmlDatei->WriteEndDocument();
    
    				   xmlDatei->Close();
    
    			 }
    };
    }
    

    Gruss
    Azo



  • Erstens, bist Du sicher dass Deine Schleife mindestens ein mal durchlaufen wird?

    Zweitens, benötigt** WriteElementString() ein vorhergehendes WriteStartElement() , um das Element einzuleiten? Falls ja, dann fehlt es hier. Falls nein, dann sollte auch das WriteEndElement() **nicht benötigt werden.

    Oder gehört das** WriteEndElement() **in Deinem Code etwa zu dem übergeordneten "eintraege" Element? Dann sollte es doch eher nach der Schleife (und nicht darin) stehen, oder ???



  • Hallo,

    1. Nein, ich bin mir nicht ganz sicher ob die Schleife mindestens einmal durchlaufen wird.

    2. End und Start hab ich nun außerhalb der For Schleife platziert.

    ps. In meiner XML Datei steht nun die Deklaration und <eintraege/>

    Gruss
    Azo



  • azo8888 schrieb:

    1. Nein, ich bin mir nicht ganz sicher ob die Schleife mindestens einmal durchlaufen wird.

    Dann finde das doch mal zuerst raus 😉

    (Entweder indem Du es im Debugger nachverfolgst oder indem Du einfach mal ein prinf("Test123\n") in die Schleife einbaust)



  • Das hier ist mein umgebauter Code - allerdings steht immer noch nichts in der XML Datei.

    // die Einstellungen setzen
    				 XmlWriterSettings ^einstellungen = gcnew XmlWriterSettings;
    
    				 einstellungen->Indent = true;
    
    				 Datei = "C:\\ILSxml\\Datei.xml";
    
    				 // Die Datei erzeugen
    				 XmlWriter ^xmlSchreiben = XmlWriter::Create(Datei, einstellungen);
    
    				 xmlSchreiben->WriteStartDocument();
    
    				 // Die Wurzel schreiben
    				 xmlSchreiben->WriteStartElement("eintraege");				
    
    				 for (Int32 i = 0; i < listBox1->SelectedIndex; i++)
    				 {
    
    					 // den Knoten eintrag erzeugen
    					 xmlSchreiben->WriteStartElement("eintrag");
    					 // die Einträge schreiben
    					 xmlSchreiben->WriteElementString("Ausgabe",listBox1->SelectedItem->ToString());
    					 // den Knoten abschließen
    					 xmlSchreiben->WriteEndElement();
    				 }					
    
    				 xmlSchreiben->WriteEndDocument();
    
    				 xmlSchreiben->Close();
    
    			 }
    };
    }
    


  • 1. Siehe meinen vorangegangenen Post!

    2. Bist Du sicher, dass bei der Benutzung von WriteElementString() zusätzlich ein vorangestelltes WriteStartElement() und ein nachgestelltes WriteEndElement() benötigt wird?

    (Meinem Verständnis nach ist WriteElementString() eine Kurzform für WriteStartElement() + WriteString() + WriteEndElement(), oder sehe ich das falsch?)



  • 1. Ja habe ich gesehen - die Schleife wird durchlaufen.

    2. also laut meinem Verständnis ist das WriteStartElement nicht unbedingt nötig. Ich habe es aber trotzdem drin, damit hier der "Eintrag" erstellt wird und anschließend über den Befehl WriteStartString der "Untereintrag" erstellt wird.

    3. Verstehe nicht was daran falsch ist, vermutlich nur ein kleiner Fehler.

    Gruss



  • Hier ein kleiner Test:

    habe alles ohne FOR SCHLEIFE gemacht - der eingegebene Text aus dem Textfeld wird einwandfrei in die XML Datei übernommen sobald der Button gedrückt wird.

    private: System::Void buttonEintrag_Click(System::Object^  sender, System::EventArgs^  e) {
    
    				 //Text aus dem Textfeld in die ListBox hinzufügen
    
    				 listBox1->Items->Add(textBox1->Text);
    
    				// textBox1->Text = "";
    
    				 // die Einstellungen setzen
    				 XmlWriterSettings ^einstellungen = gcnew XmlWriterSettings;
    
    				 einstellungen->Indent = true;
    
    				 Datei = "C:\\ILSxml\\Datei.xml";
    
    				 // Die Datei erzeugen
    				 XmlWriter ^xmlSchreiben = XmlWriter::Create(Datei, einstellungen);
    
    				 xmlSchreiben->WriteStartDocument();
    
    				 // Die Wurzel schreiben
    				 xmlSchreiben->WriteStartElement("eintraege");				
    
    					 // den Knoten eintrag erzeugen
    					 xmlSchreiben->WriteStartElement("eintrag");
    					 // die Einträge schreiben
    					 xmlSchreiben->WriteElementString("Ausgabe",textBox1->Text->ToString());
    					 // den Knoten abschließen
    					xmlSchreiben->WriteEndElement();
    
    				 xmlSchreiben->WriteEndDocument();
    
    				 xmlSchreiben->Close();
    
    			 }
    


  • Also bei mir liefert der folgende Code:

    using namespace System;
    using namespace System::Xml;
    
    int main(array<System::String ^> ^args)
    {
    	//Init Settings
    	XmlWriterSettings ^settings = gcnew XmlWriterSettings;
    	settings->Indent = true; 
    
    	// Start Document
    	XmlWriter ^xmlSchreiben = XmlWriter::Create("D:\\Temp\\Test123.xml", settings);
    	xmlSchreiben->WriteStartDocument();
    
    	// Create Root Element
    	xmlSchreiben->WriteStartElement("Entries");
    
    	// Create Entries
    	for(int i = 0; i < 16; i++)
    	{
    		xmlSchreiben->WriteElementString("MyEntry", System::String::Format("Eintrag #{0}", i));
    	}
    
    	// Close Document
    	xmlSchreiben->WriteEndDocument();
    	xmlSchreiben->Close(); 
    
    	return 0;
    }
    

    ...die folgende Ausgabe:

    <?xml version="1.0" encoding="utf-8"?>
    <Entries>
      <MyEntry>Eintrag #0</MyEntry>
      <MyEntry>Eintrag #1</MyEntry>
      <MyEntry>Eintrag #2</MyEntry>
      <MyEntry>Eintrag #3</MyEntry>
      <MyEntry>Eintrag #4</MyEntry>
      <MyEntry>Eintrag #5</MyEntry>
      <MyEntry>Eintrag #6</MyEntry>
      <MyEntry>Eintrag #7</MyEntry>
      <MyEntry>Eintrag #8</MyEntry>
      <MyEntry>Eintrag #9</MyEntry>
      <MyEntry>Eintrag #10</MyEntry>
      <MyEntry>Eintrag #11</MyEntry>
      <MyEntry>Eintrag #12</MyEntry>
      <MyEntry>Eintrag #13</MyEntry>
      <MyEntry>Eintrag #14</MyEntry>
      <MyEntry>Eintrag #15</MyEntry>
    </Entries>
    


  • okey stimmt, bei mir auch.
    Dann liegt der Fehler doch in meiner For Schleife - die Schleife bei Dir läuft 16 mal durch, meine sollte aber die Anzahl der Einträge in der ListBox zählen und so oft durchlaufen

    Hier muss der Fehler liegen:

    [code]
    for (Int32 i = 0; i < listBox1->SelectedIndex; i++) {

    xmlSchreiben->WriteStartElement("eintrag");

    xmlSchreiben->WriteElementString("Ausgabe",listBox1->SelectedItem->ToString());

    xmlSchreiben->WriteEndElement();
    }

    [\code]



  • Ich weiss nicht genau, was du bezwecken willst, könnte mir aber vorstellen, dass der gezeigte Code, nicht das tut was du erwartest.

    ListBox.SelectedIndex gibt dir den Index des aktuell selektierten Elements zurück.
    http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.selectedindex(v=vs.110).aspx
    Falls nichts selektiert ist, gibt es -1 zurück.

    ➡ Die for-Schleife wird kein einziges Mal durchlaufen, falls nichts selektiert ist
    ➡ Die for-Schleife wird vom ersten bis eins vor dem selektierten Element durchlaufen, falls ein Element selektiert ist

    ListBox.SelectedItem gibt dir das aktuell selektierte Element zurück.
    http://msdn.microsoft.com/en-us/library/system.windows.forms.listbox.selecteditem(v=vs.110).aspx

    Suchst du vielleicht ListBox.Items.Count und ListBox.Items[Index]?
    Das heisst, dass im Schleifenrumpf bei jedem Durchgang dasselbe Objekt für die Ausgabe genommen wird.


Anmelden zum Antworten