Autor Beitrag
Schoppenhonne
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Sa 06.03.21 08:25 
Hallo liebe Community,

ich bin kein C# Crack und stehe von daher vor einem Problem. Ich möchte mir meine Arbeit an der Arbeit erleichtern und mir ein kleines C#-Tool basteln. Es soll XML-Dateien auslesen und in eine Datenbank schreiben können. Mit Einfachen XML-Files bekomme ich das hin:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
<Content>
  <Category>
    <CategoryName>NameA</CategoryName>
    <CategorySomething>SomethingA</CategorySomething>
    <CategoryOne>SomeoneA</CategoryOne>
    <CategoryItem>Abababa</CategoryItem>
  </Category>
  <Category>
    <CategoryName>NameB</CategoryName>
    <CategorySomething>SomethingB</CategorySomething>
    <CategoryOne>SomeoneB</CategoryOne>
    <CategoryItem>Ikikiki</CategoryItem>
  </Category>
  <Category>
    <CategoryName>NameC</CategoryName>
    <CategorySomething>SomethingC</CategorySomething>
    <CategoryOne>SomeoneC</CategoryOne>
    <CategoryItem>Tvtvtvt</CategoryItem>
  </Category>
</Content>


Aber mein XML-File ist leider so:
ausblenden volle Höhe XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
<Content>
  <Category>
    <CategoryName>NameA</CategoryName>
    <CategorySomething>SomethingA</CategorySomething>
    <CategoryOne>SomeoneA</CategoryOne>
    <CategoryChild>
      <CategoryItem>Abababa</CategoryItem>
      <CategoryItem>Cdcdcdc</CategoryItem>
      <CategoryItem>Efefefe</CategoryItem>
      <CategoryItem>Ghghghg</CategoryItem>    
    </CategoryChild>
  </Category>
  <Category>
    <CategoryName>NameB</CategoryName>
    <CategorySomething>SomethingB</CategorySomething>
    <CategoryOne>SomeoneB</CategoryOne>
    <CategoryChild>
      <CategoryItem>Ikikiki</CategoryItem>
      <CategoryItem>Lmlmlml</CategoryItem>
      <CategoryItem>Nononon</CategoryItem>
      <CategoryItem>Pspspsp</CategoryItem>    
    </CategoryChild>
  </Category>
  <Category>
    <CategoryName>NameC</CategoryName>
    <CategorySomething>SomethingC</CategorySomething>
    <CategoryOne>SomeoneC</CategoryOne>
    <CategoryChild>      
      <CategoryItem>Tvtvtvt</CategoryItem>
      <CategoryItem>Uwuwuwu</CategoryItem>
      <CategoryItem>Xzxzxzx</CategoryItem>
      <CategoryItem>Qqqqqqq</CategoryItem>
    </CategoryChild>
  </Category>
</Content>


Die Klasse hierfür habe ich mir schon bei xmltocsharp erstellen lassen:
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
using System;
using System.Xml.Serialization;
using System.Collections.Generic;
namespace Xml2CSharp
{

  [XmlRoot(ElementName="Content")]
  public class Content {
    [XmlElement(ElementName="Category")]
    public List<Category> Category { get; set; }
  }
  
  
  [XmlRoot(ElementName="Category")]
  public class Category {
    [XmlElement(ElementName="CategoryName")]
    public string CategoryName { get; set; }
    [XmlElement(ElementName="CategorySomething")]
    public string CategorySomething { get; set; }
    [XmlElement(ElementName="CategoryOne")]
    public string CategoryOne { get; set; }
    [XmlElement(ElementName="CategoryChild")]
    public CategoryChild CategoryChild { get; set; }
  }


  [XmlRoot(ElementName="CategoryChild")]
  public class CategoryChild {
    [XmlElement(ElementName="CategoryItem")]
    public List<string> CategoryItem { get; set; }
  }

}

Nun hapert es aber beim Auslesen.

Was ich habe ist:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Category>));
StreamReader sr = new StreamReader("additions.xml");
                
List<Category> listSelection = (List<Category>)xmlSerializer.Deserialize(sr);
MessageBox.Show("De-Serialization*s Successfull");


Da komme ich aber leider nicht weiter.

Ich finde zwar viele Beispiele, die könnten aber nur mein einfaches XML-File auslesen. Das bekomme ich selber hin.

Hat jemand eine Idee, ein Vorschlag, wo ich suchen könnte oder könnte mir bitte jemand helfen?

Vielen Dank und ein schönes Wochenende.

Liebe Grüße
Schoppenhonne


Sorry, ich finde aber keine Möglichkeit, den Code übersichtlich einzurücken. Mein Text hier sieht noch übersichtlich aus, aber die Vorschau belehrt mich etwas besseren. Sorry.

Moderiert von user profile iconTh69: XML-Tags hinzugefügt
Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Sa 06.03.21 10:19 
Hallo und :welcome:

du möchtest doch den Content auslesen (nicht eine einzelne Category), also
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<Content>));
StreamReader sr = new StreamReader("additions.xml");
                
List<Content> listSelection = (List<Content>)xmlSerializer.Deserialize(sr);
MessageBox.Show("De-Serialization*s Successfull");

Edit: Code weiter unten korrigiert...

PS: Mittels der "Bereiche" kannst du Code-Tags (C#, XML, ...) setzen - alternativ direkt im Beitrag z.B. [cs]...[/cs] oder [xml]...[/xml] schreiben (ich habe deinen Beitrag dementsprechend editiert).


Zuletzt bearbeitet von Th69 am So 07.03.21 14:20, insgesamt 3-mal bearbeitet
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 06.03.21 14:21 
Crosspostings bitte verlinken

myCSharp: XML-Datei mit Array in Array Deserialisieren

Moderiert von user profile iconTh69: URL-Titel hinzugefügt.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Sa 06.03.21 14:48 
Abgesehen davon:

Die CategoryChild-Klasse brauchst Du nicht.
Stattdessen kannst Du die CategoryChild-Property auch so definieren:
ausblenden C#-Quelltext
1:
2:
3:
4:
[XmlArray(ElementName = "CategoryChild")]
[XmlArrayItem(ElementName = "CategoryItem")]
public List<string> CategoryChild { get; set; }
// Ich würde sie aber "CategoryItems" nennen.

In der Liste sind dann die CategoryItem-Werte drin.
Wenn neben dem String später noch mehr Werte dazu kommen sollen, lohnt sich natürlich ein anderer Aufbau mit einer eigenen Klasse:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
public class CategoryItem
{
    // Das ist dann der Wert im CategoryItem-Element
    [XmlText]
    public string Value { get; set; }

    // Hier die zusätzlichen Daten vom CategoryItem-Element

    // Beispiel:
    [XmlAttribute(AttributeName = "Data")]
    public string Value2 { get; set; }
}


Bei der CategoryChild-Property nimmst Du dann anstelle des Strings einfach die CategoryItem-Klasse.
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: Sa 06.03.21 16:12 
Hallo Ihr beiden,
vielen Dank für Eure liebe Unterstützung.
Ich bin unterwegs und schaue mir das später an
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 13:29 
Die einfache XML-Datei bekomme ich gefüllt und auch ausgelesen (was viel wichtiger ist für mich). Der Einfachheit halber schreibe ich alles in eine DataGridView (WinForms):

Die Klasse (vereinfacht):
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
[XmlRoot(ElementName = "Content")]
    public class ContentClass
    {
        [XmlElement(ElementName = "Category")]
        public List<CategoryClass> Category { get; set; }

        [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsi { get; set; }
        [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsd { get; set; }
    }


    [XmlRoot(ElementName = "Category")]
    public class CategoryClass
    {
        [XmlElement(ElementName = "CategoryName")]
        public string CategoryName { get; set; }

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

        [XmlElement(ElementName = "CategoryOne")]
        public string CategoryOne { get; set; }

        [XmlElement(ElementName = "CategoryItem")]
        //public List<string> CategoryItem { get; set; }
        public string CategoryItem { get; set; }
    }



Das Formular (ohne Content, weil das öffnende und schließende Tag nicht so wichtig ist):
ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
public partial class Form1 : Form
{
        XmlSerializer xs;

        List<CategoryClass> lc;
        //List<List<Category>> llc;

        public Form1()
        {
            InitializeComponent();

            lc = new List<CategoryClass>();
            //llc = new List<List<Category>>();
            xs = new XmlSerializer(typeof(List<CategoryClass>));
            //xs = new XmlSerializer(typeof(List<List<Category>>));


        }

        private void button1_Click(object sender, EventArgs e)
        {
        
            FileStream fs = new FileStream("content.xml", FileMode.Create, FileAccess.Write);
            CategoryClass cc = new CategoryClass();
            cc.CategorySomething = int.Parse(someText.Text);
            cc.CategoryName = nameText.Text;
            cc.CategoryOne = oneText.Text;
            cc.CategoryItem = itemText.Text;

            lc.Add(cc);

            xs.Serialize(fs, lc);

            fs.Close();

        }

        private void button2_Click(object sender, EventArgs e)
        {

            FileStream fs = new FileStream("content.xml", FileMode.Open, FileAccess.Read);
            lc = (List<CategoryClass>)xs.Deserialize(fs);
            //llc = (List<List<CategoryClass>>)xs.Deserialize(fs);

            dataGridView1.DataSource = lc;
            //dataGridView1.DataSource = llc;
            fs.Close();
        }
 }



Wenn ich jetzt aber in das Array "Category" noch ein Array "CategoryItem" (zwischen "CategoryChild") einfügen und auslesen will (besonders auslesen), bekomme ich eine Fehlermeldung.

(Die auskommentierten Zeilen sind meine Versuche für Array in Array)

Was mache ich falsch? Ich wäre für jeden Tipp dankbar.

Vielen Dank und einen schönen Sonntag.

LG
Schoppenhonne
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 07.03.21 13:44 
Zitat:
Das Formular (ohne Content, weil das öffnende und schließende Tag nicht so wichtig ist):


Wenn dein root Element ein <Content> ist musst du es auch mitdeserialisieren. Die eine Ebene mit einlesen kostet auch eher nix. Wenn du in tieferen Ebenen was hast was du nicht brauchst und auch alles darunter nichts braucht kann man schauen das nicht mit zu derialisiseren (also z.b CategoryChild und alles darunter). Aber mitten drin was weglassen (oder am Anfang) im Pfad zu den Knoten ist nicht.
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 13:51 
Das ist ja rasant geantwortet, vielen Dank.

Na gut, dann lasse ich nichts weg.
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 13:54 
Jetzt bekomme ich hier eine Fehlermeldung:
ausblenden C#-Quelltext
1:
lc = (List<ContentClass>)xs.Deserialize(fs);					


"Fehler im Dokument"
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 13:55 
Hier ist mein Formular, jetzt auch mit "Content".

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
namespace DeSerialize
{
    public partial class Form1 : Form
    {
        XmlSerializer xs;


        List<ContentClass> lc;
        //List<List<Category>> llc;

        public Form1()
        {
            InitializeComponent();

            lc = new List<ContentClass>();
            //llc = new List<List<Category>>();
            xs = new XmlSerializer(typeof(List<ContentClass>));
            //xs = new XmlSerializer(typeof(List<List<Category>>));


        }

        private void button1_Click(object sender, EventArgs e)
        {

            /*
            FileStream fs = new FileStream("content.xml", FileMode.Create, FileAccess.Write);
            CategoryClass cc = new CategoryClass();
            cc.CategorySomething = int.Parse(someText.Text);
            cc.CategoryName = nameText.Text;
            cc.CategoryOne = oneText.Text;
            cc.CategoryItem = itemText.Text;

            lc.Add(cc);

            xs.Serialize(fs, lc);

            fs.Close();
            */




            FileStream fs = new FileStream("contenttoll.xml", FileMode.Create, FileAccess.Write);
            ContentClass cc = new ContentClass();
            //cc.CategorySomething = int.Parse(someText.Text);
            //cc.CategoryName = nameText.Text;
            //cc.CategoryOne = oneText.Text;
            //////cc.CategoryChild.CategoryItem = itemText.Text;

            lc.Add(cc);

            xs.Serialize(fs, lc);

            fs.Close();

        }

        private void button2_Click(object sender, EventArgs e)
        {


            FileStream fs = new FileStream("contenttoll.xml", FileMode.Open, FileAccess.Read);
            lc = (List<ContentClass>)xs.Deserialize(fs);
            //llc = (List<List<CategoryClass>>)xs.Deserialize(fs);

            dataGridView1.DataSource = lc;
            //dataGridView1.DataSource = llc;
            fs.Close();
        }
    }
}
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 13:56 
Das "Schreiben" habe ich auskommentieren müssen, weil das jetzt gar nicht mehr geht.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 07.03.21 14:18 
Sorry, hatte in meiner Antwort einfach deinen Code genommen und Content eingefügt, aber es ist ja keine Liste, sondern nur ein Root-Element, also
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Content));
StreamReader sr = new StreamReader("additions.xml");

Content content = (Content)xmlSerializer.Deserialize(sr);
MessageBox.Show("De-Serialization*s Successfull");


PS: Alle Klassen, welche die Schnittstelle IDisposable implementieren, benötigen noch bei der Benutzung einen Aufruf von Dispose(). Eleganter geht dies mit der using-Anweisung:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Content));
using (StreamReader sr = new StreamReader("additions.xml"))
{
  Content content = (Content)xmlSerializer.Deserialize(sr);

  MessageBox.Show("De-Serialization*s Successfull");
}
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 15:14 
Hey, super, vielen Dank TH69, keine Fehlermeldung mehr. Und wie komme ich nun die Daten, die wahrscheinlich in "Content" stecken?`

In eine DataGridView packen klappt so leider nicht:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Content));
using (StreamReader sr = new StreamReader("contenttoll.xml"))
{
    Content content = (Content)xmlSerializer.Deserialize(sr);

    MessageBox.Show("De-Serialization*s Successfull");

    dataGridView1.DataSource = content;
}


Eigentlich will ich ja auch über die Daten verfügen, um sie in eine Datenbank zu packen oder aber in einem Excel-File auszzugeben.

Darf ich bitte noch mal um einen Tipp bitten? Keine Bange, mit der DB-Verbindung und Datenschaufeln komme ich schon klar. Nur muss ich die Daten erst mal haben.


Vielen Dank auch für Deinen Tipp mit using. Habe ich schon oft gesehen. Aber keine Ahnung, was Du mit der Schnittstelle "IDisposable" oder dem Aufruf von "Dispose()" meinst.

Ich kenne mich ziemlich gut mit SQL aus. Oder PHP/MySQL. Und etwas Javascript. Vielleicht kann ich mich da mal revenchieren.

LG
Schoppenhonne

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: So 07.03.21 16:19 
Wenn deine Klasse aus deinem ersten Beitrag so lautet:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
[XmlRoot(ElementName="Content")]
public class Content {
    [XmlElement(ElementName="Category")]
    public List<Category> Category { get; set; }
}

(auch wenn du die Eigenschaft besser in der Mehrzahl Categories nennen solltest, da es sich ja um eine Liste handelt)

Dann kannst du so darauf zugreifen.
ausblenden C#-Quelltext
1:
dataGridView1.DataSource = content.Category; // bzw. Categories					


Und bzgl. IDisposable s. Verwenden von Objekten, die IDisposable implementieren.

PS: Mit SQL kenne ich mich auch gut aus - und Javascript benutze ich nicht, da ich keine Webentwicklung mache (auch wenn ich es vor Jahren mal gelernt und auch als Nachhilfe gegeben habe).
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 07.03.21 16:30 
Zitat:
Eigentlich will ich ja auch über die Daten verfügen, um sie in eine Datenbank zu packen oder aber in einem Excel-File auszzugeben.


Ein übliches Vorgehen ist verschiedene Klassenmodelle zu haben und dazwischen zu transformieren.
Hier hast du aus dem xml Klassen generiert die halt optimiert sind zum lesen /schreiben aus/in XML Dateien. Das bedeutet aber nicht das die ebenso gut geeignet zum Darstellen in einer UI.

Ich würde dir raten dir zu überlegen wie die Darstellung in einem Grid aussehen soll. Dazu dann die passende Klasse(n) zu schreiben und dann zwischen diesem Klassenmodel und das das du zum lesen/schreiben verwendest zu transformieren(mappen/kopieren oder wie man den Vorgang auch immer nennen möchte).

Das gleiche wenn du irgendwas in eine andere Richtung machen willst (wie z.b. in einer DB ablegen). Schaff dir ein passendes Klassenmodell.
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 07.03.21 16:38 
Zitat:
Keine Bange, mit der BD-Verbinung und Daten-schaufeln komme ich schon klar

Sorry, aber das bezweifle ich. Nicht falsch verstehen, aber die Arbeit mit Datenbanken ist eben nicht nur SQL ;)
Du solltest dich in die Grundlagen einarbeiten, im Internet zusammen kopieren oder in Foren schnipselhaft Teil-Probleme erfragen, funktioniert zwar auch, dauert aber deutlich länger.
Und glaub mir: Auf lange Sicht kann es sehr frustrierend werden, bei jeder Kleinigkeit auf Hilfe angewiesen zu sein, am Ende profitierst Du nur.

Das kostenlose Buch "Visual C# 2012" behandelt neben den C#-Grundlagen auch XML-Serialisierung und die Arbeit mit Datenbanken auf mehrere Arten.
Den Teil mit WPF kannst Du ja überspringen, wenn Du unbedingt bei WinForms bleiben willst.
Von dem Buch gibt's auch eine aktuellere Version von 2019, die gibt's meines Wissens nach aber nicht mehr kostenlos.

Und bezüglich Excel kann ich das Framework "ClosedXML" sehr empfehlen, das baut auf Microsofts OpenXML-Implementierung auf, macht das ganze aber um Welten intuitiver - zumindest sehe ich das so.
Ist zwar eine Weile her, dass ich damit gearbeitet habe, aber da hat es mir meine Arbeit von ein paar Tagen auf ein paar Stunden reduziert, besonders bei spezielleren Funktionen von Excel.
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 16:41 
Also erstmal, habe ich mich eben dumm angestellt, was mir oft sehr leicht fällt. :lol:

Das Grid fülle ich so:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
using (StreamReader sr = new StreamReader("contenttoll.xml"))
{
  Content content = (Content)xmlSerializer.Deserialize(sr);
  
  MessageBox.Show("De-Serialization*s Successfull");

  dataGridView1.DataSource = content.Category;
}


Aber es zeigt leider immer noch die einfache XML an, ohne das innere Array.

Ich habe sehr viel gesucht und gelesen, die letzten Tage, aber ich finde keinee Beispile, die annähernd so sind, wie das, was ich wegen dem blöden XML-File brauche.
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4700
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 07.03.21 17:05 
Zitat:
Aber es zeigt leider immer noch die einfache XML an, ohne das innere Array.


Mir wäre nicht bewußt das ein Standard Grid geschachtelte Tabellen anzeigen könnte und das bräuchte es hier.
Ich hätte erwartet das du in deinem Grid eine Spalte "CategoryChild" zu sehen bekommst. Der Inhalt einer Zelle wäre dann die Ausgabe von CategoryChild.ToString().
Und ToString() liefert im Standardfall wenn man das nichts überschrieben hat den Klassennamen den du bestimmt nicht sehen willst in einem Grid.

Überleg dir was du im Grid wie sehen willst. Also insbesondere wenn du Category als Zeilen hast wie das CategoryItem den in einer Zelle aussehen soll es (ist ja selbst eine Liste).

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Schoppenhonne Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 19



BeitragVerfasst: So 07.03.21 18:14 
Hallo Ralf Jansen,

vielen Dank für Deinen Tipp. Ich kenne das vom SQL, von Excel und von PHP/MySQL, dass eine Tabelle dann halt mehrere Datensätze hat, wo dann nur das Feld "CategoryItem" einen anderen Inhalt aufweisen würde.

Und Du hast korrekt vermutet, dass mein Grid die Spalte "CategorieChild" aufweist. Siehe Screenshot.

Und ich muss nicht unbedingt einen Grid haben. Ich habe nur gedacht, von dort die Datensätze in die DB zu schaufeln. Ich habe keine Ahnung, wie ich es sonst machen sollte. Dein Tipp heute Nachmittag war schon wertvoll und ich habe nun auch noch mehr Klassen:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
namespace DeSerialize
{

    [XmlRoot(ElementName = "Content")]
    public class Content
    {
        [XmlElement(ElementName = "Category")]
        public List<Category> Category { get; set; }

        [XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsi { get; set; }
        [XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
        public string Xsd { get; set; }
    }


    [XmlRoot(ElementName = "Category")]
    public class Category
    {
        [XmlElement(ElementName = "CategoryName")]
        public string CategoryName { get; set; }

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

        [XmlElement(ElementName = "CategoryOne")]
        public string CategoryOne { get; set; }


        [XmlElement(ElementName = "CategoryChild")]
        public CategoryChild CategoryChild { get; set; }
        //[XmlArray(ElementName = "CategoryChild")]
        //[XmlArrayItem(ElementName = "CategoryItem")]
        //public List<string> CategoryChild { get; set; }

        [XmlElement(ElementName = "CategoryItem")]
        ////public List<string> CategoryItem { get; set; }
        public string CategoryItem { get; set; }




    }

    [XmlRoot(ElementName = "CategoryChild")]
    public class CategoryChild
    {
        [XmlElement(ElementName = "CategoryItem")]
        public List<string> CategoryItem { get; set; }
    }

    [XmlRoot(ElementName = "CategoryItem")]
    public class CategoryItem
    {
        [XmlText]
        public string Value { get; set; }
    }
}


Aber ich weiß trotzdem nicht, ob das so okay ist und wie es weitergeht.

LG
Schoppenhonne
Einloggen, um Attachments anzusehen!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mo 08.03.21 09:35 
Wie Ralf schon geschrieben hat, könntest du einfach ToString überschreiben:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
public class CategoryChild
{
   [XmlElement(ElementName = "CategoryItem")]
   public List<string> CategoryItem { get; set; } // auch hier besser in der Mehrzahl: CategoryItems

   public virtual string ToString()
   {
       return CategoryItem.Join('\n'); // oder ein anderes Trennzeichen z.B. ','
   }
}

Weitere Formatierung etc. s. z.B. Hierarchical Data Into DataGridView in C#.

Ansonsten könntest du auch ein 2. Steuerelement für die Anzeige des jeweils selektierten Category-Datensatzes benutzen, s. z.B. A Detailed Data Binding Tutorial (unter "Hierarchical data binding" ff.).

Und dann gibt es noch diverse andere spezialisierte DataGridView-Implementierungen, z.B. Nested DataGridView in Windows Forms C# sowie .NET (WinForms) Grid Control with Collapse/Expand Capabilities (aber meist propietär).

PS: Du nutzt so aber die Klasse CategoryItem nicht (mehr).
Müßte es nicht so lauten
ausblenden C#-Quelltext
1:
public List<CategoryItem> CategoryItems { get; set; }					
?
Und dann auch ToString() in der Klasse überschreiben.