Frank Dzaebel, erstellt am: 21.10.06, zuletzt geändert:
30.04.07
Kategorie: XML, .NET-Version: 2.0, [Download] [Download2] [Download3]
[Download4]
Hier wird gezeigt, wie man von XML automatisch zu einer Klassen-Repräsentation innerhalb des Codes kommen kann und durch ein automatisch erstelltes DataSet einen Schreib-Lese-Zugriff bekommt. Weiterführende
Links dazu zum Beispiel:
- XML Schema Definition-Tool (Xsd.exe)
- Generieren einer relationalen DataSet-Struktur aus einem XML-Schema (XSD)
- Zuordnen von XSD-Einschränkungen (XML-Schema) zu DataSet-Einschränkungen
- Generieren von DataSet-Beziehungen aus einem XML-Schema (XSD)
- Verstehen der Wechselbeziehung zwischen Einschränkungen und Beziehungen
- Bindungsunterstützung für XML-Schema in .NET Framework
- Mit dem XmlSerializer eigene Objekte serialisieren und deserialisieren
1) XML-Datei
Gegeben ist eine Ausgangs-XML-Datei (Bezirke.xml) wie hier:
<?xml version="1.0" standalone="yes"?>
<Bezirke>
<GruppeVersandBezirk Name="Bezirk001" Anzahl="2000" />
<GruppeVersandBezirk Name="Bezirk002" Anzahl="1220" />
<Bezirk Name="Bezirk001">
<BezirkDaten Name="Müller" Anzahl="200" Verteilt="189" />
<BezirkDaten Name="Maier" Anzahl="600" Verteilt="456" />
<BezirkDaten Name="Huber" Anzahl="1200" Verteilt="1111" />
</Bezirk>
<Bezirk Name="Bezirk002">
<BezirkDaten Name="Müller" Anzahl="200" Verteilt="190" />
<BezirkDaten Name="Maier" Anzahl="600" Verteilt="456" />
<BezirkDaten Name="Huber" Anzahl="1200" Verteilt="1111" />
</Bezirk>
<Ergebnis SummeVerteilt="1783" />
</Bezirke>
|
 |
2) XSD und CS-Datei erstellen
- Öffnen des "Visual Studio Command Prompt" über Menü: Programme /
"Microsoft Visual Studio 2005" / "Visual Studio Tools" / "Visual Studio 2005 Command Prompt"
- Navigieren in das Verzeichnis der XML-Datei mittels cd ..... und folgendes eingeben:
- xsd Bezirke.xml
- Dadurch wird automatisch eine Bezirke.xsd erzeugt.
|
- |
Nun kann in VisualStudio-Projekt die Bezirke.xsd (und somit automatisch Bezirke.Designer.cs) zum Projekt hinzugefügt werden.
(Der Visual Studio Designer erzeugt die cs-Datei deswegen, weil in der xsd-Datei ein Hint: msdata:IsDataSet="true" ist. Das ist genau das, was der Befehl "xsd /l:cs /d Bezirke.xsd" tuen würde. Wenn man eine XML-Datei öffnet, dann über Menü "XML- SchemaErstellen" ein Schema erstellen würde und "IsDataSet="true" nebst Deklaration einfügen würde, so würde der Designer auch ohne Umweg über die Kommandozeile das DataSet erstellen). |
|
|
 |
Bezirke.Designer.cs:
|
Es ensteht also folgendes Schema:

Wenn man im DataSet "MappingType.Hidden" durch "MappingType.Attribute" ersetzt, würde später auch die Bezirk_Id-Spalte sichtbar sein, falls gewünscht.
3) Lesen, Schreiben und Binden der Daten in einer der Form:
Das Lesen und Schreiben der Daten kann einfach über ReadXml und WriteXml geschehen.
Die Daten können zum Beispiel an den DataSource eines DataGridView gebunden werden.
using System;
using System.Windows.Forms;
using System.Data;
namespace XmlSchreibenLesen
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Bezirke bezirke = new Bezirke();
string xmlPfad = "../../Bezirke.xml";
private void Form1_Load(object sender,EventArgs e)
{
bezirke.ReadXml(xmlPfad);
foreach (DataTable dt in bezirke.Tables)
comboBox1.Items.Add(dt.TableName);
comboBox1.SelectedIndex = 0;
}
private void comboBox1_SelectedIndexChanged(object sender,EventArgs e)
{
dataGridView1.DataSource = bezirke.Tables[comboBox1.SelectedItem.ToString()];
}
private void btnSpeichern_Click(object sender,EventArgs e)
{
bezirke.WriteXml(xmlPfad);
}
}
}
4) Zugriffe wie Ändern, Selektieren, Löschen der Daten [Download3]
using System;
using System.Windows.Forms;
using XsdGen.xsdSchema.nameSpaceBezirkeNeu;
using ps = XsdGen.xsdSchema.nameSpaceBezirkeNeu.Bezirke;
using System.Reflection;
using System.Diagnostics;
using System.Data;
namespace XsdGen
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender,EventArgs e)
{
#region Einlesen / Ansehen ..
string path = "../../Bezirke.xml";
p = new ps(); p.ReadXml(path); p.WriteXml(path); //Bezirke.xml ansehen
int lastBdIndex = p.BezirkDaten.Rows.Count - 1;
int lastBrIndex = p.Bezirk.Rows.Count - 1;
#endregion
#region Fall a) "Huber" lesen und ändern.
//IST: <BezirkDaten Name="Huber" Anzahl="1200" Verteilt="1111" Bezirk_Id="1"/>
//SOLL:<BezirkDaten Name="Huber" Anzahl="1200" Verteilt="877" Bezirk_Id="1"/>
/*Z.B.*/ p.BezirkDaten[lastBdIndex].Verteilt = "877";
//Gehen Sie mit der Maus über BezirkDaten und klicken Sie auf die Lupe.
/*Oder*/ GetBdRow(1,"Huber")[CN.Verteilt] = 876;
p.WriteXml(path); // jetzt Bezirke.xml ansehen
#endregion
#region Fall b) Bezik_ID ändern
//IST: <BezirkDaten Name="Huber" Anzahl="1200" Verteilt="1111" Bezirk_Id="0"/>
//SOLL:<BezirkDaten Name="Huber" Anzahl="1200" Verteilt="1111" Bezirk_Id="1"/>
/*Z.B.*/ // p.BezirkDaten.Rows[2][CN.Bezirk_Id] = 1;
/*Oder*/ GetBdRow(0,"Huber")[CN.Bezirk_Id] = 1;
p.WriteXml(path);
#endregion
#region Fall c) Row, Zeile löschen
//IST:<BezirkDaten Name="Huber" Anzahl="1200" Verteilt="1111" Bezirk_Id="1"/>
//SOLL: [nichts]
/*Z.B.*/ // p.BezirkDaten.Rows.RemoveAt(2);
/*oder*/ p.BezirkDaten.Rows.Remove(GetBdRow(1,"Huber"));
#endregion
}
#region Methoden, Globals
static ps p;
/// <summary> //p.BezirkDaten.Bezirk_IdColumn-Namen</summary>
static class CN
{
public static string Bezirk_Id = "Bezirk_Id";
public static string Verteilt = "Verteilt";
public static string Name = "Name";
}
private DataRow GetBdRow(int bezirk_id,string name)
{
string auswahl = String.Format("{0}={1} and {2}='{3}'",CN.Bezirk_Id,bezirk_id,CN.Name,name);
DataRow[] rows = p.BezirkDaten.Select(auswahl);
if (rows.Length == 0) throw new Exception("In Bezirk " + bezirk_id + " gibt es keinen " + name);
return rows[0];
}
#endregion
}
}