Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 6. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Das Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Strukturen und Enumerationen
7 Fehlerbehandlung und Debugging
8 Auflistungsklassen (Collections)
9 Generics – Generische Datentypen
10 Weitere C#-Sprachfeatures
11 LINQ
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 XML
15 Multithreading und die Task Parallel Library (TPL)
16 Einige wichtige .NET-Klassen
17 Projektmanagement und Visual Studio 2012
18 Einführung in die WPF und XAML
19 WPF-Layout-Container
20 Fenster in der WPF
21 WPF-Steuerelemente
22 Elementbindungen
23 Konzepte von WPF
24 Datenbindung
25 Weitere Möglichkeiten der Datenbindung
26 Dependency Properties
27 Ereignisse in der WPF
28 WPF-Commands
29 Benutzerdefinierte Controls
30 2D-Grafik
31 ADO.NET – Verbindungsorientierte Objekte
32 ADO.NET – Das Command-Objekt
33 ADO.NET – Der SqlDataAdapter
34 ADO.NET – Daten im lokalen Speicher
35 ADO.NET – Aktualisieren der Datenbank
36 Stark typisierte DataSets
37 Einführung in das ADO.NET Entity Framework
38 Datenabfragen des Entity Data Models (EDM)
39 Entitätsaktualisierung und Zustandsverwaltung
40 Konflikte behandeln
41 Plain Old CLR Objects (POCOs)
Stichwort

Download:
- Beispiele, ca. 62,4 MB

Jetzt Buch bestellen
Ihre Meinung?

Spacer
Visual C# 2012 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2012

Visual C# 2012
Rheinwerk Computing
1402 S., 6., aktualisierte und erweiterte Auflage 2013, geb., mit DVD
49,90 Euro, ISBN 978-3-8362-1997-6
Pfeil 14 XML
Pfeil 14.1 Grundlagen
Pfeil 14.2 XML-Dokumente
Pfeil 14.2.1 Wohlgeformte und gültige XML-Dokumente
Pfeil 14.2.2 Die Regeln eines wohlgeformten XML-Codes
Pfeil 14.2.3 Kommentare
Pfeil 14.2.4 Verarbeitungsanweisungen
Pfeil 14.2.5 Reservierte Zeichen in XML
Pfeil 14.2.6 CDATA-Abschnitte
Pfeil 14.2.7 Namensräume (Namespaces)
Pfeil 14.3 Die Gültigkeit eines XML-Dokuments
Pfeil 14.3.1 XML Schema Definition (XSD)
Pfeil 14.3.2 Ein XML-Dokument mit einem XML-Schema verknüpfen
Pfeil 14.3.3 Die Struktur eines XML-Schemas
Pfeil 14.4 Die Klasse »XmlReader«
Pfeil 14.4.1 XML-Dokumente mit einem »XmlReader«-Objekt lesen
Pfeil 14.4.2 Validieren eines XML-Dokuments
Pfeil 14.5 Eigenschaften und Methoden der Klasse »XmlReader«
Pfeil 14.6 Die Klasse »XmlWriter«
Pfeil 14.6.1 Die Methoden der Klasse »XmlWriter«
Pfeil 14.7 Navigation durch XML (XPath)
Pfeil 14.7.1 Die Klasse »XPathNavigator«
Pfeil 14.7.2 XPath-Ausdrücke
Pfeil 14.7.3 Der Kontextknoten
Pfeil 14.7.4 Beispiele mit XPath-Ausdrücken
Pfeil 14.7.5 Knotenmengen mit der »Select«-Methode
Pfeil 14.7.6 Auswerten von XPath-Ausdrücken
Pfeil 14.8 Das Document Object Model (DOM)
Pfeil 14.8.1 Allgemeines
Pfeil 14.8.2 Arbeiten mit »XmlDocument«
Pfeil 14.8.3 »XmlDocument« und »XPathNavigator«
Pfeil 14.8.4 Die Klasse »XmlNode« (Operationen mit Knoten)
Pfeil 14.8.5 Manipulieren einer XML-Struktur
Pfeil 14.8.6 Ändern eines Knotens
Pfeil 14.8.7 Löschen in einem XML-Dokument
Pfeil 14.9 Serialisierung mit »XmlSerializer«
Pfeil 14.9.1 XML-Serialisierung mit Attributen steuern
Pfeil 14.10 LINQ to XML
Pfeil 14.10.1 Allgemeines
Pfeil 14.10.2 Die Klassenhierarchie von LINQ to XML
Pfeil 14.10.3 Die Klasse »XElement«
Pfeil 14.10.4 Die Klasse »XDocument«
Pfeil 14.10.5 Navigation im XML-Dokument
Pfeil 14.10.6 Änderungen am XML-Dokument vornehmen

Rheinwerk Computing - Zum Seitenanfang

14.8 Das Document Object Model (DOM)Zur nächsten Überschrift


Rheinwerk Computing - Zum Seitenanfang

14.8.1 AllgemeinesZur nächsten ÜberschriftZur vorigen Überschrift

Die Klasse XmlReader bietet nur einen schreibgeschützten, vorwärts gerichteten Lesezugriff, mit XmlWriter nur einen vorwärts gerichteten Schreibzugriff. Zum Bearbeiten des Inhalts eines Elements, zum Einfügen neuer oder zum Löschen enthaltener Elemente gibt es weder Methoden noch Eigenschaften.

Abhilfe schafft das Document Object Model, kurz DOM genannt. Hierbei handelt es sich um eine Spezifikation einer Schnittstelle für den beliebigen Zugriff auf die Elemente in einem XML-Dokument. Diese Spezifikation ist vom W3-Konsortium definiert worden.

Beim Arbeiten auf Basis von DOM wird das komplette XML-Dokument in den Speicher geladen und wird in Form einer Baumstruktur dargestellt. Wenn XML in das Dokumentobjektmodell (DOM) eingelesen wird, werden die einzelnen Teile in Knoten umgesetzt. Diese enthalten zusätzliche Metadaten über sich selbst, z. B. ihren Knotentyp und ihre Werte. Der Knotentyp besteht aus seinem Objekt und bestimmt, welche Aktionen ausgeführt und welche Eigenschaften festgelegt oder abgerufen werden.

Wie das intern realisiert wird, möchte ich Ihnen anhand des folgenden einfachen XML-Codes zeigen:

<Person>
<Name>Fischer</Name>
</Person>

Dieser XML-Code wird im Speicher durch die in der folgenden Abbildung gezeigte Knotenstruktur dargestellt.

Abbildung

Abbildung 14.7 Einfache DOM-Struktur

Das Person-Element wird zu einem XmlElement-Objekt, ebenso wie das folgende Element Name. Der Elementinhalt wird zu einem XmlText-Objekt. Die Methoden und Eigenschaften von XmlElement unterscheiden sich von denen, die für ein XmlText-Objekt verfügbar sind. Folglich ist es wichtig, zu wissen, in welchen Knotentyp das XML-Markup umgesetzt wird, da der Knotentyp bestimmt, welche Aktionen ausgeführt werden können.

Projizieren wir dieses kleine Beispiel auf ein größeres XML-Dokument, präsentiert sich dieses im Speicher als komplexe Baumstruktur. Zur Verdeutlichung diene die folgende XML-Struktur.

<?xml version="1.0" encoding="utf-8" ?>
<Personen>
<Person>
<Name>Fischer</Name>
<Alter>45</Alter>
<Ort="Aachen" PLZ="52072"></Ort>
</Person>
</Personen>

Listing 14.47 XML-Dokument der in Abbildung 14.7 gezeigten DOM-Struktur

In Abbildung 14.8 sehen Sie, wie dieses an sich noch sehr kleine XML-Fragment durch eine bereits verhältnismäßig komplexe Struktur im Speicher repräsentiert wird.

Abbildung

Abbildung 14.8 Darstellung eines XML-Dokuments als Baumstruktur


Rheinwerk Computing - Zum Seitenanfang

14.8.2 Arbeiten mit »XmlDocument«Zur nächsten ÜberschriftZur vorigen Überschrift

XML-Daten laden

Ein XmlDocument-Objekt enthält manipulierbare XML-Daten auf der Basis von DOM. Nach der Instanziierung der Klasse stehen Ihnen mit Load und LoadXml zwei Methoden zur Verfügung, um das Objekt mit Daten zu füllen.

Der Methode Load können Sie eine URL als Zeichenfolge übergeben. Die URL kann eine lokale Datei oder eine HTTP-URL (also eine Webadresse) sein. Weitere Überladungen erlauben auch die Übergabe eines Stream-, TextReader- oder XmlReader-Objekts.

XmlDocument doc = new XmlDocument();
doc.Load(@"D:\Personen.xml");

Liegt das XML-Dokument in einer Zeichenfolge vor, bietet sich die Methode LoadXml an. Bedingung ist, dass die Zeichenfolge wohlgeformtes XML beschreibt, da ansonsten eine XmlException geworfen wird.

XmlDocument doc = new XmlDocument();
doc.LoadXml("<Person><Zuname>Franz</Zuname></Person>");

Die Variable doc beschreibt nun das im Speicher befindliche XML-Dokument. Mit den Eigenschaften und Methoden des XmlDocument-Objekts können Sie anschließend beliebig durch die Baumstruktur der Knoten navigieren und diese beliebig bearbeiten.


Rheinwerk Computing - Zum Seitenanfang

14.8.3 »XmlDocument« und »XPathNavigator«Zur nächsten ÜberschriftZur vorigen Überschrift

Es gibt noch eine andere Variante, durch die Baumstruktur zu navigieren. Ausgangspunkt sind dabei die Methoden und Eigenschaften der Klasse XPathNavigator. Dazu wird auf die Referenz des XmlDocuments die Methode CreateNavigator aufgerufen, deren Rückgabewert ein XPathNavigator-Objekt ist.

XmlDocument doc = new XmlDocument();
doc.Load(@"D:\Personen.xml");
XPathNavigator navi = doc.CreateNavigator();

Die Kombination zwischen einem XPathNavigator und einem XmlDocument bietet den Vorteil, die zahlreichen Navigationsmöglichkeiten von XPathNavigator nutzen zu können. Allerdings hat dieser Verbund einen gravierenden Nachteil, denn das XML-Dokument muss zweimal im Speicher abgebildet werden, was bei der Größe vieler XML-Dokumente aus performance- und ressourcentechnischer Sicht nicht mehr akzeptabel ist.

Geänderte Daten speichern

Einer der großen Vorteile von DOM gegenüber anderen Techniken ist, dass die XML-Daten geändert und gespeichert werden können. Dazu stellt das XmlDocument-Objekt die Methode Save bereit, der als Argument eine den Speicherort beschreibende Zeichenfolge oder ein Stream-, TextWriter- oder XmlWriter-Objekt übergeben wird.


Rheinwerk Computing - Zum Seitenanfang

14.8.4 Die Klasse »XmlNode« (Operationen mit Knoten)Zur nächsten ÜberschriftZur vorigen Überschrift

Ein Objekt vom Typ XmlNode repräsentiert im Speicher einen einzelnen Knoten eines XML-Dokuments. XmlNode ist eine abstrakte Klasse, die viele Methoden und Eigenschaften bereitstellt, um durch eine Knotenstruktur zu navigieren, sie zu ändern oder auch zu ergänzen.

Zahlreiche Ableitungen von XmlNode beschreiben die unterschiedlichen Knotentypen innerhalb eines XML-Dokuments und erweitern die geerbten Eigenschaften und Methoden um knotenspezifische. Zu diesen Ableitungen gehören auch die Klassen, die beispielsweise ein Attribut oder die XML-Deklaration beschreiben, sowie die Klasse XmlDocument. Einen Überblick über die Vererbungshierarchie erhalten Sie in Abbildung 14.9.

Abbildung

Abbildung 14.9 Die Ableitungen der Klasse »XmlNode«

Wenn Sie sich die Liste der Eigenschaften in der Dokumentation der Klasse XmlNode ansehen, werden Sie feststellen, dass sich die meisten zwei Kategorien zuordnen lassen: Sie werden einige Eigenschaften finden, die rein der informellen Analyse eines Knotens dienen, und eine zweite Gruppe, die der Navigation dient.

Den Inhalt eines Knotens auswerten

Sehen wir uns in der folgenden Tabelle zuerst die Eigenschaften an, die informellen Charakter haben.

Tabelle 14.14 »XmlNode«-Eigenschaften, die informelle Informationen liefern

Eigenschaft Beschreibung

InnerText

Ruft die verketteten Werte des Knotens und sämtlicher ihm untergeordneten Knoten ab oder legt diese fest. Die zurückgegebene Zeichenfolge enthält kein XML-Markup.

InnerXml

Liefert das Markup, das nur die untergeordneten Knoten dieses Knotens
darstellt, oder legt dieses fest.

IsReadOnly

Gibt an, ob der Knoten schreibgeschützt ist.

Name

Ruft den Bezeichner des Knotens ab.

NamespaceURI

Ruft den Namespace-URI dieses Knotens ab.

NodeType

Ruft den Typ des Knotens ab.

OuterXml

Ruft das Markup ab, das den aktuellen und alle ihm untergeordneten
Knoten darstellt.

Prefix

Ruft das Namespace-Präfix dieses Knotens ab oder legt dieses fest.

Value

Liefert den Wert des Knotens oder legt ihn fest. Der zurückgegebene Wert hängt vom Knotentyp ab. Beispielsweise liefert der Typ XmlNodetype.Element null, während es sich bei einem Knoten vom Typ Text um den Inhalt des Textknotens handelt.

Ein Wort noch zu der Eigenschaft NodeType, die uns den Typ des aktuellen Knotens liefert. Diese Eigenschaft ist vom Typ der Enumeration XmlNodeType. Um einen Überblick über einige der wichtigeren Mitglieder dieser Enumeration zu erhalten, sehen Sie sich bitte die folgende Tabelle an.

Tabelle 14.15 Member der Enumeration »XmlNodeType« (Auszug)

Konstante Beschreibung

Element

Beschreibt ein Element (z. B. <Person>).

Attribute

Beschreibt ein Attribut.

Text

Beschreibt den Textinhalt eines Knotens.

CDATA

Beschreibt einen CDATA-Abschnitt.

EntityReference

Beschreibt eine Entität (z. B. &lt;).

Comment

Beschreibt einen Kommentar.

WhiteSpace

Beschreibt Leerraum zwischen Markup.

Die Ausgaben der Eigenschaften InnerText, InnerXml, Name und Value hängen vom Knotentyp ab. Handelt es sich dabei beispielsweise um XmlNodeType.Element oder XmlNodeType.Attribute, wird der entsprechende Bezeichner ausgegeben. Nicht jeder Knotentyp hat einen Bezeichner, der auswertbar ist. Daher liefert Name für diese Knotengruppe einen alternativen Text, z. B. #text, #comment oder #cdata-section. Andererseits haben einige Knoten keinen Inhalt, der mit Value abgerufen werden könnte. Dann ist die Rückgabe null.

Nehmen wir an, im XML-Fragment

<Person>Franz</Person>

würde die Variable node vom Typ XmlNode den Knoten Person beschreiben. (Anmerkung: Befindet sich das genannte Element in einem XML-Dokument, muss zuerst dorthin navigiert werden.) Rufen wir die Name-Eigenschaft ab, wird uns

Person

ausgegeben. InnerXml und InnerText liefern beide gleichermaßen

Franz

zurück, während Value keinen Inhalt hat und null ist. Navigieren wir nun weiter, so dass node auf den Textknoten zeigt, wird Name die Ausgabe

#text

haben und Value sowie InnerText den gewünschten Inhalt Franz anzeigen.

Das folgende Beispielprogramm zeigt die informellen Ausgaben im Zusammenhang. An LoadXml wird dabei eine XML-Struktur übergeben. Anschließend wird mit der Eigenschaft DocumentElement das Stammelement der Struktur abgerufen und in der Variablen root gespeichert. Der Rückgabewert der Eigenschaft DocumentElement ist vom Typ XmlElement, auf das danach exemplarisch Eigenschaften aufgerufen werden.

// Beispiel: ..\Kapitel 14\XmlNodeSample
static void Main(string[] args) {
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Person><Name Zuname='Müller'><Alter>34</Alter>" +
"Peter</Name></Person>");
XmlNode root = doc.DocumentElement;
// Eigenschaft 'Name'
Console.WriteLine("Name:");
Console.WriteLine("{0}\n", root.Name);
// Eigenschaft 'OuterXml'
Console.WriteLine("OuterXml:");
Console.WriteLine("{0}\n", root.OuterXml);
// Eigenschaft 'InnerXml'
Console.WriteLine("InnerXml:");
Console.WriteLine("{0}\n", root.InnerXml);
// Eigenschaft 'Value'
Console.Write("Value:");
if (root.Value == null)
Console.WriteLine(" <leer>\n");
else
Console.WriteLine("\n{0}\n",root.Value);
// Eigenschaft 'InnerText'
Console.WriteLine("InnerText:");
Console.WriteLine("{0}",root.InnerText);
Console.ReadLine();
}

Listing 14.48 Das Beispielprogramm »XmlNodeSample«

Die Ausgabe an der Konsole können Sie in Abbildung 14.10 sehen.

Abbildung

Abbildung 14.10 Die Ausgabe des Beispiels »XmlNodeSample«

Mit den Eigenschaften eines »XmlNode«-Objekts navigieren

Jetzt wollen wir uns die Eigenschaften eines XmlNode-Objekts anschauen, die der Navigation in einer XML-Struktur dienen. Auch hier sollten Sie sich zunächst einen Überblick über die Eigenschaften anhand einer Tabelle verschaffen.

Tabelle 14.16 Eigenschaften des »XmlNode«-Objekts zur Navigation

Eigenschaft Beschreibung

Attributes

Diese Eigenschaft ruft eine Auflistung vom Typ XmlAttributCollection ab, die die Attribute des aktuellen Knotens enthält.

ChildNodes

Ruft alle untergeordneten Knoten des Knotens ab.

FirstChild

Ruft das erste untergeordnete Element des aktuellen Knotens ab.

HasChildNodes

Ruft einen Wert ab, der angibt, ob dieser Knoten über untergeordnete Knoten verfügt.

Item

Ruft das erste untergeordnete Element mit dem angegebenen Bezeichner ab.

LastChild

Ruft das letzte untergeordnete Element des aktuellen Knotens ab.

NextSibling

Ruft den nächsten nebengeordneten Knoten ab, der dem aktuellen Knoten folgt.

ParentNode

Ruft das übergeordnete Element des aktuellen Knotens ab.

PreviousSibling

Ruft den vorhergehenden nebengeordneten Knoten des aktuellen Knotens ab.

Die Vorgehensweise beim Einsatz dieser Eigenschaften ähnelt der Navigation mit XmlReader oder XPathNavigator. Von jedem beliebigen XmlNode-Objekt aus können Sie mit den Eigenschaften FirstChild, LastChild, NextSibling, PreviousSibling und ParentNode zum nächsten untergeordneten Element, zum letzten untergeordneten Element, zum nächsten bzw. letzten nebengeordneten Element oder gar zum übergeordneten Element wechseln.

Die Collection »XmlChildNodes«

Die Eigenschaft ChildNodes liefert eine Liste aller direkt untergeordneten Knoten ab. Diese wird durch den Typ XmlNodeList beschrieben. Viele Möglichkeiten bietet diese Liste nicht, aber Sie können diese Liste in einer Schleife durchlaufen, sich mit Count die Anzahl der untergeordneten Knoten besorgen oder mit Item einen bestimmten Knoten an der angegebenen Indexposition in der Liste abfragen.

XmlDocument doc = new XmlDocument();
doc.Load(@"D:\Personen.xml");
XmlNode root = doc.DocumentElement;
XmlNodeList nodeList = root.ChildNodes;
foreach (XmlNode node in nodeList)
{
[...]
}

Listing 14.49 Die Liste aller direkt untergeordneten Knoten abfragen

Die Schleifenvariable node kann natürlich dazu benutzt werden, um den damit aktuell referenzierten Knoten weiter zu untersuchen, ob er seinerseits selbst untergeordnete Knoten hat.

Um einen bestimmten untergeordneten Knoten auszuwerten, können Sie sich die Referenz auf das diesen Knoten beschreibende XmlNode-Objekt mit

XmlNode node = irgendeinKnoten.ChildNodes[2];

oder alternativ auch mit

XmlNode node = nodeList[2];

besorgen. In beiden Fällen erhalten Sie die Referenz auf den dritten untergeordneten Knoten.

Auswerten eines kompletten XML-Dokuments

Um ein XML-Dokument komplett auszuwerten, bietet sich ein rekursiver Aufruf einer Methode an, in der eine Untersuchung des aktuellen Knotens stattfindet. Hier spielen die beiden Eigenschaften Attributes und HasChildNodes ihre ganze Stärke aus.

// Beispiel: ..\Kapitel 14\XmlNodeNavigation
static void Main(string[] args) {
XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\Personen.xml");
XmlNode root = doc.DocumentElement;
GetNodes(root, 0);
Console.ReadLine();
}
static void GetNodes(XmlNode node, int level) {
switch (node.NodeType) {
// Prüfen, ob es sich um ein Element handelt
case XmlNodeType.Element:
Console.Write(new string(' ', level * 2));
Console.Write("<{0}", node.Name);
// Prüfen, ob das aktuelle Element Attribute hat
if (node.Attributes != null) {
foreach (XmlAttribute attr in node.Attributes)
Console.Write(" {0}='{1}'", attr.Name, attr.Value);
}
Console.Write(">");
// Prüfen, ob das aktuelle Element untergeordnete Elemente hat
if (node.HasChildNodes)
foreach (XmlNode child in node.ChildNodes) {
if (child.NodeType != XmlNodeType.Text)
Console.WriteLine();
GetNodes(child, level + 1);
}
break;
// Prüfen, ob es sich um auswertbare Daten handelt
case XmlNodeType.Text:
Console.Write(node.Value);
break;
}
}

Listing 14.50 Das Beispielprogramm »XmlNodeNavigation«

Liefert Attributes einen Wert ungleich null, hat das aktuelle Element Attribute, die in einer Schleife abgefragt werden können. HasChildNodes liefert einen Boolean. Ist dieser true, kann die Liste der untergeordneten Knoten mit der Eigenschaft ChildNodes durchlaufen werden. Dabei kommt es zu einem rekursiven Aufruf der benutzerdefinierten Methode GetNodes.

In diesem Beispiel wurden keine Namespaces und Präfixe zur eindeutigen Identifizierung der Elemente in der XML-Datei benutzt. Bei der Navigation spielt das keine Rolle, da etwaig vorhandene Namespaces als Attribute bewertet werden und die Elemente samt dem Präfix ausgegeben werden. Der Parameter level der Methode ChildNodes dient dazu, optisch ansprechende Einzüge in der Ausgabe darstellen zu können.

Abbildung

Abbildung 14.11 Ausgabe des Beispiels »XmlNodeNavigation«

XPath-Ausdrücke verwenden

Um ein Element in einer XML-Struktur eindeutig zu adressieren, können Sie auch einen XPath-Ausdruck festlegen. Die Klasse XmlNode kennt zwei Methoden, denen Sie einen XPath-Ausdruck übergeben können: SelectNodes und SelectSingleNode. Beide Methoden werden auch von der Klasse XmlDocument unterstützt und können daher auch auf die Referenz des XmlDocument-Objekts aufgerufen werden.

SelectNodes liefert eine Auflistung des Typs XmlNodeList mit allen gefundenen Elementen zurück, die dem XPath-Ausdruck entsprechen. Das folgende Codefragment gibt die Liste aller Zunamen aus der XML-Datei Personen.xml aus.

XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\Personen.xml");
XmlNodeList liste = doc.SelectNodes("//Person//Zuname");
foreach(XmlNode temp in liste)
Console.WriteLine("Name: {0}", temp.InnerXml);

Listing 14.51 Mit »SelectNodes« mehrere Knoten abrufen

Sind Sie nur am ersten Element interessiert, liefert der Aufruf von SelectSingleNode genau dieses.

XmlNodeList liste = root.SelectNodes("//Person//Zuname");

Beide Methoden haben zudem noch jeweils eine Überladung, die ein Objekt vom Typ XmlNamespaceManager erwartet, mit dem Sie die Präfixe der Elemente auflösen können. Diese Klasse wurde bereits in Abschnitt 14.7.6 behandelt.

Suche nach bestimmten Elementen

Im folgenden Beispielprogramm wird demonstriert, wie die Inhalte bestimmter Elemente ausgewertet werden können. Im Mittelpunkt steht dabei die Methode GetElementsByTagName, der das zu durchsuchende Element angegeben wird.

// Beispiel: ..\Kapitel 14\SearchForElements
static void Main(string[] args){
XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\Personen.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList elemList = root.GetElementsByTagName("Zuname");
// Resultate anzeigen
for (int i = 0; i < elemList.Count; i++) {
Console.WriteLine(elemList[i].InnerXml);
}
Console.ReadLine();
}

Listing 14.52 Beispielprogramm »SearchForElements«

Als Ergebnis werden die Namen aller im XML-Dokument enthaltenen Personen ausgegeben.


Rheinwerk Computing - Zum Seitenanfang

14.8.5 Manipulieren einer XML-StrukturZur nächsten ÜberschriftZur vorigen Überschrift

Zahlreiche Methoden sind in den Klassen XmlDocument, XmlNode und XmlNodeList definiert, um neue Knoten hinzuzufügen, vorhandene zu ändern oder gar zu löschen. Um einen besseren Überblick über die sich bietenden Möglichkeiten zu bekommen, wird den drei Operationen des Hinzufügens, Editierens und Löschens jeweils ein eigener Abschnitt gewidmet.

Hinzufügen eines Knotens

Um zu zeigen, wie zusätzliche Knoten einer XML-Struktur hinzugefügt werden, soll im nächsten Codefragment zunächst eine komplett neue XML-Struktur bereitgestellt werden, die wie folgt aussieht:

<?xml version="1.0" encoding="ibm850" ?>
<!--Dies ist ein Kommentar-->
<Personen>
<Person>Peter</Person>
</Personen>

Code, der dies leistet, würde wie folgt lauten:

XmlNode nodePerson, nodeName;
XmlDocument doc = new XmlDocument();
XmlComment cmt = doc.CreateComment("Dies ist ein Kommentar");
doc.AppendChild(cmt);
XmlNode nodeRoot = doc.CreateElement("Personen");
doc.AppendChild(nodeRoot);
nodePerson = doc.CreateElement("Person");
nodeRoot.AppendChild(nodePerson);
nodeName = doc.CreateTextNode("Peter");
nodePerson.AppendChild(nodeName);
doc.Save(Console.Out);

Listing 14.53 Einen Knoten einem XML-Dokument hinzufügen

Die resultierende XML-Struktur weist insgesamt vier Knoten auf, die der Reihe nach erzeugt werden. Dazu stellt die Klasse XmlDocument mehrere passende CreateXxx-Methoden bereit. Im Code werden mit CreateComment, CreateElement und CreateTextNode ein Kommentar, zwei Elementknoten und ein Textknoten erzeugt.

Die Basisklasse aller Knoten, XmlNode, vererbt an alle Ableitungen, also auch an XmlDocument, die Methode AppendChild. Der Aufruf dieser Methode auf einen bestimmten Knoten bewirkt, dass die dem Parameter übergebene XmlNode-Referenz zu einem untergeordneten Knoten des Knotens wird, auf dem die Methode aufgerufen wird.

Nach allem bleibt festzuhalten, dass es sich immer um zwei Schritte handelt, einen neuen Knoten einem existierenden XML-Dokument hinzuzufügen:

  • Erzeugen des neuen Knotens mit einer Create-Methode auf die Referenz des XmlDocument-Objekts.
  • Aufrufen der Methode AppendChild auf den Knoten, dem der neue Knoten hinzugefügt werden soll. Die Referenz des neuen Knotens wird dabei als Argument dem Methodenaufruf übergeben.

Wird ein neues XML-Dokument erzeugt, dürfen Sie auf dessen Referenz nur einmal die CreateElement-Methode aufrufen, da das so hinzugefügte Element das Wurzelelement des XML-Dokuments beschreibt, von dem es bekanntlich zur Sicherstellung der Wohlgeformtheit nur eines geben darf.

In der folgenden Tabelle finden Sie eine Übersicht der gängigsten CreateXxx-Methoden von XmlDocument.

Tabelle 14.17 Die »Create«-Methoden der Klasse »XmlDocument« (Auszug)

Methode Beschreibung

CreateAttribute

Erstellt ein neues Objekt vom Typ XmlAttribute.

CreateCDataSection

Erstellt ein neues Objekt vom Typ XmlCDataSection.

CreateComment

Erstellt ein neues Objekt vom Typ XmlComment.

CreateDefaultAttribute

Erstellt ein Standardattribut mit dem angegebenen Präfix, lokalen Namen und Namespace-URI.

CreateElement

Erstellt ein neues Objekt vom Typ XmlElement.

CreateNode

Erstellt ein neues Objekt vom Typ XmlNode.

CreateProcessingInstruction

Erstellt ein neues Objekt vom Typ XmlProcessingInstruction.

CreateTextNode

Erstellt ein neues Objekt vom Typ XmlText.

CreateXmlDeclaration

Erstellt ein neues Objekt vom Typ XmlDeclaration.


Rheinwerk Computing - Zum Seitenanfang

14.8.6 Ändern eines KnotensZur nächsten ÜberschriftZur vorigen Überschrift

Um einen Knoten zu ändern, benötigen Sie zuerst die Referenz auf den entsprechenden Knoten. Dabei kommen die diversen Navigationsmethoden in Frage oder, was deutlich besser ist, ein XPath-Ausdruck. Das zeigt das folgende Beispielprogramm, das zum Ziel hat, in der Datei Personen.xml das Alter von Klaus Meier neu festzulegen.

// Beispiel: ..\Kapitel 14\EditXmlNode
static void Main(string[] args) {
XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\Personen.xml");
XmlNode root = doc.DocumentElement;
// Referenz auf das zu ändernde Element besorgen
XmlNode node = root.SelectSingleNode("//Person[Zuname ='Meier']/Alter");
if (node != null)
{
XmlNode nodeAlter = node.FirstChild;
// Das Alter ändern
nodeAlter.Value = "33";
XmlNode parent = node.ParentNode;
GetNodes(parent, 0);
Console.ReadLine();
return;
}
else
{
Console.WriteLine("Der angegebene Zuname existiert nicht.");
Console.ReadLine();
}
}
static void GetNodes(XmlNode node, int level) {
switch (node.NodeType) {
// Prüfen, ob es sich um ein Element handelt
case XmlNodeType.Element:
Console.Write(new string(' ', level * 2));
Console.Write("<{0}>", node.Name);
if (node.HasChildNodes)
foreach (XmlNode child in node.ChildNodes) {
if (child.NodeType != XmlNodeType.Text)
Console.WriteLine();
GetNodes(child, level + 1);
}
break;
// Prüfen, ob es sich um auswertbare Daten handelt
case XmlNodeType.Text:
Console.Write(node.Value);
break;
}
}

Listing 14.54 Ändern eines Knotens

Nach dem Laden der Datei und der Referenzierung des Wurzelelements wird mit SelectSingleNode ein XPath-Ausdruck abgesetzt, der anhand des Elements Zuname nach Meier sucht:

 //Person[Zuname ='Meier']/Alter

Man sollte berücksichtigen, dass die entsprechende Person nicht vom XML-Dokument beschrieben wird. Der Rückgabewert der Methode SelectSingleNode ist in dem Fall null. Wird das Element Meier gefunden, liefert das Ergebnis des XPath-Ausdrucks das Element Alter und wird mit FirstChild auf den Textknoten verschoben, dessen Inhalt anschließend über die Eigenschaft Value verändert wird. Alternativ hätten Sie auch direkt die Referenz auf das Element Alter benutzen können, um die Änderung vorzunehmen. Sie müssen dann die Eigenschaft InnerText ändern:

XmlNode node = root.SelectSingleNode("//Person[Zuname ='Meier']/Alter");
if (node != null) {
node.InnerText = "33";
[...]

Um uns vom Erfolg zu überzeugen, wird am Ende das die Person Meier betreffende Element komplett ausgegeben. Hierzu dient die Methode GetNodes, die ich Ihnen in ähnlicher Form bereits in Abschnitt 14.8.4 im Beispielprogramm XmlNodeNavigation vorgestellt habe.

Attribute ändern

Um einem Element ein Attribut hinzuzufügen, muss auf die Referenz des entsprechenden Elements die Methode SetAttribute aufgerufen werden. Der Aufruf von SetAttribute erzeugt aber nur dann ein neues Attribut, wenn es ein solches namentlich noch nicht gibt. Ansonsten wird der Inhalt des gefundenen Attributs nur geändert.

Im folgenden Listing wird sowohl ein neues Attribut zu einem XmlElement hinzugefügt als auch ein vorhandenes editiert.

static void Main(string[] args) {
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Personen><Person><Name>Fischer</Name>" +
"<Daten alter='56' ort='Bonn'/></Person></Personen>");
XmlNode root = doc.DocumentElement;
string xpath = "/Personen/Person/Daten";
XmlElement node = (XmlElement)root.SelectSingleNode(xpath);
// Attribut 'ort' ändern
node.SetAttribute("ort", "Aachen");
// Attribut 'plz' hinzufügen
node.SetAttribute("plz", "52072");
// Ausgabe der XML-Struktur
Console.WriteLine(doc.InnerXml);
}

Listing 14.55 Ändern eines Attributs


Rheinwerk Computing - Zum Seitenanfang

14.8.7 Löschen in einem XML-DokumentZur nächsten ÜberschriftZur vorigen Überschrift

Löschen eines Elements

Um ein Element aus einer XML-Struktur zu entfernen, rufen Sie die Methode RemoveChild auf das übergeordnete Element des zu löschenden Elements auf. Der Methode wird die Referenz auf das Element übergeben, das entfernt werden soll. Im folgenden Codefragment wird aus der Datei die dritte Person (Petra Schmidt) gelöscht.

XmlDocument doc = new XmlDocument();
doc.Load("Personen.xml");
XmlNode root = doc.DocumentElement;
XmlNode node = root.SelectSingleNode("//Person[Zuname='Schmidt']");
root.RemoveChild(node);

Listing 14.56 Löschen eines Elements aus einem XML-Dokument

Löschen von Attributen

Zum Entfernen eines Attributs stellt Ihnen die Klasse XmlElement vier Methoden zur Verfügung, die Sie der folgenden Tabelle entnehmen können.

Tabelle 14.18 Methoden zum Löschen von Attributen

Methode Beschreibung

RemoveAllAttributes

Löscht alle angegebenen Attribute des Elements.

RemoveAttribute

Entfernt das angegebene Attribut, dessen Bezeichner der Methode übergeben wird.

RemoveAttributeAt

Entfernt den Attributknoten mit dem angegebenen Index aus dem Element.

RemoveAttributeNode

Löscht das angegebene Attribut, das als XmlAttribute-Referenz angegeben wird.

Im nächsten Codebeispiel wird exemplarisch das Attribut Ort der Person Meier gelöscht. Dabei wird die Methode RemoveAttribute verwendet. Zum Auffinden dient ein XPath-Ausdruck, dessen Rückgabe bekanntlich vom Typ XmlNode ist. Da die Löschmethode jedoch in der Klasse XmlElement definiert ist, muss das Resultat der Methode SelectSingleNode entsprechend typumgewandelt werden.

string xpath = "//Person[Zuname='Meier']/Adresse";
XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\Personen.xml");
XmlNode root = doc.DocumentElement;
XmlElement element = (XmlElement)root.SelectSingleNode(xpath);
Console.WriteLine(element.Name);
element.RemoveAttribute("Ort");

Listing 14.57 Löschen mit »RemoveAttribute«

Untergeordnete Elemente und Attribute löschen

Mit RemoveAll stellen die Klassen XmlNode und XmlElement eine Methode bereit, die gleichzeitig alle angegebenen Attribute und untergeordneten Elemente des aktuellen Knotens entfernt.

XmlDocument doc = new XmlDocument();
doc.LoadXml("<Person ort='Aachen' plz='52072'>" +
"<Name>Franz Schmitz</Name></Person>");
XmlNode root = doc.DocumentElement;
root.RemoveAll();

Listing 14.58 Löschen aller Attribute mit »RemoveAll«

Als Resultat bleibt als Ergebnis nur noch

<Person></Person>

stehen.



Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

<< zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Visual C# 2012

Visual C# 2012
Jetzt Buch bestellen


 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Rheinwerk-Shop: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Rheinwerk-Shop: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Rheinwerk-Shop: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Rheinwerk-Shop: C++ Handbuch






 C++ Handbuch


Zum Rheinwerk-Shop: C/C++






 C/C++


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo





Copyright © Rheinwerk Verlag GmbH 2013
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern