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

Inhaltsverzeichnis
Vorwort zur 5. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Weitere .NET-Datentypen
7 Weitere Möglichkeiten von C#
8 Auflistungsklassen (Collections)
9 Fehlerbehandlung und Debugging
10 LINQ to Objects
11 Multithreading und die Task Parallel Library (TPL)
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 Einige wichtige .NET-Klassen
15 Projektmanagement und Visual Studio 2010
16 XML
17 WPF – Die Grundlagen
18 WPF-Containerelemente
19 WPF-Steuerelemente
20 Konzepte der WPF
21 Datenbindung
22 2D-Grafik
23 ADO.NET – verbindungsorientierte Objekte
24 ADO.NET – Das Command-Objekt
25 ADO.NET – Der SqlDataAdapter
26 ADO.NET – Daten im lokalen Speicher
27 ADO.NET – Aktualisieren der Datenbank
28 Stark typisierte DataSets
29 LINQ to SQL
30 Weitergabe von Anwendungen
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2010 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2010

Visual C# 2010
geb., mit DVD
1295 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1552-7
Pfeil 16 XML
Pfeil 16.1 XML-Dokumente
Pfeil 16.1.1 Wohlgeformte und gültige XML-Dokumente
Pfeil 16.1.2 Regeln für wohlgeformten XML-Code
Pfeil 16.1.3 Kommentare
Pfeil 16.1.4 Verarbeitungsanweisungen
Pfeil 16.1.5 Reservierte Zeichen in XML
Pfeil 16.1.6 CDATA-Abschnitte
Pfeil 16.1.7 Namensräume (Namespaces)
Pfeil 16.2 Gültigkeit eines XML-Dokuments
Pfeil 16.2.1 XML Schema (XSD)
Pfeil 16.2.2 XML-Dokument mit einem XML Schema verknüpfen
Pfeil 16.2.3 Struktur eines XML Schemas
Pfeil 16.3 Die Klasse »XmlReader«
Pfeil 16.3.1 XML-Dokumente mit einem »XmlReader«-Objekt lesen
Pfeil 16.3.2 Validieren eines XML-Dokuments
Pfeil 16.4 Eigenschaften und Methoden der Klasse »XmlReader«
Pfeil 16.4.1 Navigation mit dem »XmlReader«
Pfeil 16.4.2 Eigenschaften und Methoden im Zusammenhang mit Attributen
Pfeil 16.4.3 Eigenschaften und Methoden im Zusammenhang mit Namespaces
Pfeil 16.4.4 Daten lesen
Pfeil 16.5 Die Klasse »XmlWriter«
Pfeil 16.5.1 Die Methoden der Klasse »XmlWriter«
Pfeil 16.6 Navigation durch XML (XPath)
Pfeil 16.6.1 Die Klasse »XPathNavigator«
Pfeil 16.6.2 XPath-Ausdrücke
Pfeil 16.6.3 Kontextknoten
Pfeil 16.6.4 Beispiele mit XPath-Ausdrücken
Pfeil 16.6.5 Knotenmengen mit der »Select«-Methode
Pfeil 16.6.6 Auswerten von XPath-Ausdrücken
Pfeil 16.7 Document Object Model (DOM)
Pfeil 16.7.1 Allgemeines
Pfeil 16.7.2 Arbeiten mit XmlDocument
Pfeil 16.7.3 XmlDocument und XPathNavigator
Pfeil 16.7.4 Die Klasse »XmlNode« (Operationen mit Knoten)
Pfeil 16.7.5 XML-Struktur manipulieren
Pfeil 16.7.6 Knoten ändern
Pfeil 16.7.7 Löschen in einem XML-Dokument
Pfeil 16.8 Serialisierung mit »XmlSerializer«
Pfeil 16.8.1 XML-Serialisierung mit Attributen steuern
Pfeil 16.9 LINQ to XML
Pfeil 16.9.1 Klassenhierarchie von LINQ to XML
Pfeil 16.9.2 Die Klasse »XElement«
Pfeil 16.9.3 Die Klasse »XDocument«
Pfeil 16.9.4 Navigation im XML-Dokument
Pfeil 16.9.5 Änderungen am XML-Dokument vornehmen


Galileo Computing - Zum Seitenanfang

16.7 Document Object Model (DOM) Zur nächsten ÜberschriftZur vorigen Überschrift


Galileo Computing - Zum Seitenanfang

16.7.1 Allgemeines Zur nächsten ÜberschriftZur vorigen Überschrift

Die Klasse XmlReader bietet nur einen schreibgeschützten vorwärtsgerichteten Lesezugriff, mit XmlWriter nur einen vorwärtsgerichteten 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 Abbildung 16.7 gezeigte Knotenstruktur dargestellt.

Abbildung 16.7 Eine 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>

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

Abbildung 16.8 Darstellung eines XML-Dokuments als Baumstruktur


Galileo Computing - Zum Seitenanfang

16.7.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 einen URL als Zeichenfolge übergeben. Der 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 ausgelöst wird.


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

Die Variable doc beschreibt nun das sich 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.


Galileo Computing - Zum Seitenanfang

16.7.3 XmlDocument und XPathNavigator Zur nächsten ÜberschriftZur vorigen Überschrift

Es gibt noch eine andere Variante, durch die Baumstruktur zu navigieren. Der 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.


Galileo Computing - Zum Seitenanfang

16.7.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 16.9.

Wenn Sie sich die Liste der Eigenschaften in der Dokumentation der Klasse XmlNode ansehen, werden Sie feststellen, dass sich die meisten Eigenschaften 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.

Abbildung 16.9 Die Ableitungen der Klasse »XmlNode«

Inhalt eines Knotens auswerten

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


Tabelle 16.14 XmlNode-Eigenschaften, die informelle Informationen liefern

Eigenschaft Beschreibung

InnerText

Ruft die verketteten Werte des Knotens und sämtlicher diesem 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 Knoten 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 ab 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 Tabelle 16.15 an.


Tabelle 16.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, sodass 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 dem danach exemplarisch Eigenschaften aufgerufen werden.


// -----------------------------------------------------
// Beispiel: ...\Kapitel 16\XmlNodeSample
// -----------------------------------------------------
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);

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

Abbildung 16.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 16.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)
{
  ...
}

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 16\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;         
  }
}

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 eventuell 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 16.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 der 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);

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 16.6.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 16\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();
}

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


Galileo Computing - Zum Seitenanfang

16.7.5 XML-Struktur manipulieren Zur 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, der Editierung und des Löschens jeweils ein eigener Abschnitt gewidmet.

Knoten hinzufügen

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 aussehen:


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);

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 immer zwei Schritte erforderlich sind, um einen neuen Knoten einem existierenden XML-Dokument hinzuzufügen:

1. Erzeugen Sie den neuen Knoten mit einer Create-Methode auf die Referenz des XmlDocument-Objekts.
2. Rufen Sie die Methode AppendChild auf dem Knoten auf, 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 Tabelle 16.17 finden Sie eine Übersicht der gängigsten CreateXxx-Methoden von XmlDocument.


Tabelle 16.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.



Galileo Computing - Zum Seitenanfang

16.7.6 Knoten ändern Zur 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 infrage 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 16\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; 
    // 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;
  }
}

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 16.7.4 im Programm XmlNodeNavigation vorgestellt habe.

Attribute ändern

Um einem Element ein Attribut hinzuzufügen, muss auf der 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 Beispielcode wird sowohl ein neues Attribut zu einem XmlElement hinzugefügt als auch ein vorhandenes editiert.


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);


Galileo Computing - Zum Seitenanfang

16.7.7 Löschen in einem XML-Dokument topZur vorigen Überschrift

Element löschen

Um ein Element aus einer XML-Struktur zu entfernen, rufen Sie die Methode RemoveChild auf dem übergeordneten 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);

Attribute löschen

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


Tabelle 16.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 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");

Untergeordnete Elemente und Attribute löschen

Mit RemoveAll stellen die Klassen XmlNode und XmlElement eine Methode bereit, die 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();

Als Resultat bleibt als Ergebnis nur noch


<Person></Person>

stehen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2010

Visual C# 2010
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2010
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