Galileo Computing < openbook > Galileo 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

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

Galileo Computing - Zum Seitenanfang

14.10 LINQ to XMLZur nächsten Überschrift


Galileo Computing - Zum Seitenanfang

14.10.1 AllgemeinesZur nächsten ÜberschriftZur vorigen Überschrift

LINQ to XML vereinigt die Fähigkeiten von DOM und die von XPath beschriebenen Möglichkeiten, die im Speicher befindlichen XML-Daten zu verwalten, abzufragen und darüber hinaus auch zu ändern. Mit LINQ to XML soll dem Entwickler, der sich vorher mit mehreren unterschiedlichen APIs auseinandersetzen musste, die Arbeit mit XML einfacher gemacht werden. Im Folgenden werden wir uns mit der in .NET 3.5 eingeführten Technik beschäftigen. Da LINQ to XML eine eigenständige API (Klassenbibliothek) ist, gestattet LINQ to XML das Arbeiten mit XML-Dokumenten, ohne dass dabei zwangsläufig LINQ-Abfragen eingesetzt werden müssen.

Damit Sie die Bibliothek einsetzen können, müssen Sie auf die Assembly System.Xml.Linq verweisen und sollten auch den gleichnamigen Namespace bekannt geben.


Galileo Computing - Zum Seitenanfang

14.10.2 Die Klassenhierarchie von LINQ to XMLZur nächsten ÜberschriftZur vorigen Überschrift

Ehe wir uns die Fähigkeiten von LINQ to XML ansehen, sollten wir einen Blick auf die Klassenbibliothek werfen. Allzu viele hat LINQ to XML nicht zu bieten, was die Einarbeitung sicherlich deutlich vereinfacht. In Abbildung 14.13 ist die Klassenhierarchie dargestellt.

Abbildung

Abbildung 14.13 Die LINQ to XML-Klassenhierarchie

Da in diesem Buch nur ein kurzer Abriss von LINQ to XML erfolgt, soll es genügen, wenn an dieser Stelle nur die wichtigsten Klassen beschrieben werden.

Tabelle 14.20 Wichtige Klassen von LINQ to XML

Klasse Beschreibung

XElement

Bei dieser Klasse handelt es sich wohl um die wichtigste von LINQ to XML. Die Klasse beschreibt einen XML-Element-Knoten, der untergeordnete Elemente enthalten kann. Die Klasse stellt eine Vielzahl von Methoden zur Verfügung, um innerhalb der XML-Struktur zu navigieren oder auch um XML-Elemente zu bearbeiten.

XDocument

XDocument ist der Klasse XElement sehr ähnlich. Das wichtigste Unterscheidungsmerkmal im Vergleich zur Klasse XElement ist, dass ein XDocument-Objekt auch XML-Deklarationen und mehrere XML-Prozessinstruktionen bearbeiten kann.

XAttribute

Diese Klasse repräsentiert XML-Attribute und stellt passende Methoden zum Verwalten und Erzeugen zur Verfügung. Die Arbeit mit Attributen ähnelt dem Arbeiten mit den Elementen. Intern werden Attribute als Name-Wert-Paar behandelt, das einem Element zugeordnet ist.

XDeclaration

Die XDeclaration wird für die Angabe der XML-Version und der Codierung benötigt.

XComment

Ein Objekt dieser Klasse stellt einen XML-Kommentar dar.

XNode

Die Klasse XNode ist abstrakt definiert und stellt ihren Ableitungen Methoden zur Bearbeitung der Elemente einer XML-Struktur zur Verfügung.

XProcessingInstruction

Diese Klasse repräsentiert eine Processing Instruction (PI).


Galileo Computing - Zum Seitenanfang

14.10.3 Die Klasse »XElement«Zur nächsten ÜberschriftZur vorigen Überschrift

XML-Daten in den Speicher laden

Um die Daten einer XML-Datei in den Speicher zu laden, wird die Methode Load der Klasse XElement aufgerufen, z. B.:

XElement xml = XElement.Load(@"D:\Personen.xml");

Der Methode Load können Sie einen Stream, ein TextReader-Objekt, ein XmlReader-Objekt oder eine Zeichenfolge übergeben. Bei der Zeichenfolge darf es sich auch um einen URI oder eine relative Angabe handeln, die dann relativ zum Anwendungsordner gilt. Darüber hinaus finden sich weitere Überladungen, die einen zweiten Parameter vom Typ LoadOptions beschreiben. Mit der Option LoadOptions.PreserveWhitespace ließe sich beispielsweise angeben, dass die Leerzeichen beibehalten werden sollen.

Es gibt auch einige wenige Fälle, in denen das XML nicht in einer Datei vorliegt oder aus einem URI bezogen wird. Stattdessen wird das XML durch eine einfache Zeichenfolge beschrieben. Für diesen Fall stellt die Klasse XElement die statische Methode Parse zur Verfügung, die ein XElement-Objekt aus einer XML-Zeichenfolge erstellt, z. B.:

string xml = "<Name>Andreas</Name>";
XElement element = XElement.Parse(xml);

XML-Daten erzeugen und speichern

Ein XElement-Objekt beschreibt als Container weitere untergeordnete Elemente. Über die Konstruktoren werden die Elemente ineinander verschachtelt, um so die gewünschte XML-Struktur abzubilden. Exemplarisch wollen wir die folgende XML-Struktur mit der LINQ to XML-API abbilden.

<?xml version="1.0" encoding="utf-8"?>
<Personen>
<Person>
<Name>Fischer</Name>
<Vorname>Manfred</Vorname>
<Alter>45</Alter>
</Person>
</Personen>

Der Code, der dieses XML erzeugt, lautet wie folgt:

XElement persons = new XElement("Personen",
new XElement("Person",
new XElement("Name", "Fischer"),
new XElement("Vorname", "Manfred"),
new XElement("Alter", "45")
)

);
persons.Save(@"D:\Personen.xml");

Listing 14.63 XML-Dokument mit LINQ to XML

Mit einer einzigen Anweisung hat man bereits das XML erzeugt – übrigens einschließlich des Prologs. Diese Anweisung in eine Zeile zu schreiben ist wenig ratsam. Sie sollten stattdessen eine Schachtelung im Code vornehmen, aus dem auch die Struktur der XML-Tags ersichtlich ist. Das ist natürlich deutlich intuitiver, als dazu beispielsweise die Klasse XmlWriter zu verwenden (vergleichen Sie dazu bitte mit dem Beispielprogramm XmlWriterSample in Abschnitt 14.6). Zum Schluss wird durch Aufruf der Methode Save das mit Code beschriebene XML in einer Datei gespeichert. Es erweist sich als vorteilhaft, dass Sie sich nicht weiter um die Endtags Gedanken machen müssen, denn diese sind bereits durch die Klammerung des Programmcodes vorgegeben und werden damit bereits zur Entwurfszeit sichergestellt.

Der Konstruktor der Klasse XElement hat drei Überladungen. In unserem Beispiel haben wir die folgende benutzt:

public XElement(XName name, Object content)

Sehen wir uns zuerst den ersten Parameter an. Dieser ist vom Typ XName. Übergeben wir an dieser Stelle einen String, wird die Zeichenfolge hinter den Kulissen implizit in ein XName-Objekt konvertiert. Das vereinfacht die Übergabe an den ersten Parameter ganz deutlich.

Dem zweiten Parameter können wir ein x-beliebiges Objekt übergeben. Am meisten kommen hier die folgenden zum Einsatz:

  • ein XElement-Objekt, das als untergeordnetes Element eingefügt wird
  • eine Zeichenfolge, die als Textinhalt bewertet wird
  • ein XAttribute-Objekt, das als Attribut dem Element hinzugefügt wird
  • eine XProcessingInstruction oder ein XComment
  • ein XText-Objekt, das häufig einen CData-Wert beschreibt

Namespaces definieren

Um einen Namespace festzulegen, benutzen Sie das Element XAttribute.

XNamespace ns = "http://www.tollsoft.de";
XElement persons = new XElement(ns + "Personen");

Dabei wird das folgende XML erzeugt:

<Personen xmlns="http://www.tollsoft.de" />

Um einen Namespace mit einem Präfix zu verbinden, können Sie an das Element ein XAttribute-Element anhängen. Übergeben Sie dem Konstruktor zuerst den durch die Eigenschaft Xmlns des XNamespace-Elements beschriebenen Namespace, und verbinden Sie diesen mit dem Präfix. Dem zweiten Parameter übergeben Sie die XNamespace-Variable.

Das hört sich kompliziert an, deshalb dazu auch sofort ein Beispiel. Nehmen wir dazu das Beispiel von oben. Es soll ein Namespace definiert werden (»http://www.tollsoft.de«), der als Präfix pers vor jedem XML-Element angegeben werden soll. Der Code sieht dann wie folgt aus:

XNamespace ns = "http://www.tollsoft.de";
XElement persons = new XElement(ns + "Personen",
new XAttribute(XNamespace.Xmlns + "pers", ns),
new XElement(ns + "Person",
new XElement(ns + "Name", "Fischer"),
new XElement(ns + "Vorname", "Manfred"),
new XElement(ns + "Alter", "45")
)
);

Listing 14.64 Namespaces mit LINQ to XML

Aus diesem Codefragment resultiert das folgende XML-Dokument:

<?xml version="1.0" encoding="utf-8"?>
<pers:Personen xmlns:pers="http://www.tollsoft.de">
<pers:Person>
<pers:Name>Fischer</pers:Name>
<pers:Vorname>Manfred</pers:Vorname>
<pers:Alter>45</pers:Alter>
</pers:Person>
</pers:Personen>

Listing 14.65 Resultierendes XML aus Listing 14.64


Galileo Computing - Zum Seitenanfang

14.10.4 Die Klasse »XDocument«Zur nächsten ÜberschriftZur vorigen Überschrift

Die beiden Klassen XElement und XDocument sind sich sehr ähnlich. Mit beiden können Sie XML-Daten laden und speichern sowie die XML-Daten bearbeiten. Der wesentlichste Unterschied ist, dass mit XDocument auch die XML-Deklaration bearbeitet werden kann und mehrere XML-Prozessinstruktionen hinzugefügt werden können. Möchten Sie also in den geladenen Daten auf XML-Kommentare, die XML-Deklaration oder XML-Prozessinstruktionen zugreifen, ist die Klasse XDocument jedenfalls die bessere Wahl. Dazu ein Beispiel.

XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XComment("Dokument enthält Personen"),
new XProcessingInstruction("XML-StyleSheet", "meine.xsl"),
new XElement("Personen",
new XElement( ...));

Listing 14.66 Einsatz der Klasse »XDocument«


Galileo Computing - Zum Seitenanfang

14.10.5 Navigation im XML-DokumentZur nächsten ÜberschriftZur vorigen Überschrift

Die beiden Klassen XElement und XDocument unterscheiden sich nicht wesentlich. Das wurde bereits eben erwähnt. Die gleiche Aussage gilt auch hinsichtlich der Navigationsmöglichkeiten. XElement und XDocument weisen zahlreiche Möglichkeiten zur Navigation durch ein XML-Dokument auf. Hier auf alle einzugehen, würde den Rahmen des Buches sprengen. Allerdings sollen Sie mit den wichtigsten Navigationsmethoden, die auch oft als Achsenmethoden bezeichnet werden, das Prinzip der Navigation sehen.

Als Ausgangspunkt dient uns dabei eine XML-Datei, die die Daten von drei Personen und einem Kunden beschreibt:

<?xml version="1.0" encoding="utf-8"?>
<Personen>
<Person>
<Name>Fischer</Name>
<Vorname>Manfred</Vorname>
<Alter>45</Alter>
<Adresse Ort="Aachen" Strasse="Gasse 1"></Adresse>
</Person>

<Kunde>
<Name>Tollsoft AG</Name>
</Kunde>

<Person>
<Name>Meier</Name>
<Vorname>Franz</Vorname>
<Alter>76</Alter>
<Adresse Ort="Ulm" Strasse="Avenue 12"></Adresse>
</Person>

<Person>
<Name>Schmidt</Name>
<Vorname>Detlef</Vorname>
<Alter>28</Alter>
<Adresse Ort="Bonn" Strasse="Weg 34"></Adresse>
</Person>
</Personen>

Listing 14.67 Das XML-Dokument für die folgenden Ausführungen

Die Methode »Element«

Die Methode Element gestattet uns, ein Element aufgrund seines Namens zu selektieren. Wir wollen das sofort testen und schreiben den folgenden Code, um auf das erste Person-Element zuzugreifen.

XElement root = XElement.Load(@"..\..\Personen.xml");
XElement element = root.Element("Person");
Console.WriteLine(element);

Listing 14.68 Auswahl eines Elements mit der Methode »Element«

Hier wird die Load-Methode der Klasse XElement dazu benutzt, um auf die Datei Personen.xml zuzugreifen. Die Variable root referenziert danach das Stammelement Personen des geöffneten XML-Dokuments. Darauf rufen Sie die Methode Element auf und übergeben ein XName-Objekt. Alternativ lässt sich auch der Bezeichner des gesuchten Elements als Zeichenfolge angeben, die implizit in den Typ XName konvertiert wird. Die Ausgabe an der Konsole wird lauten:

<Person>
<Name>Fischer</Name>
<Vorname>Manfred</Vorname>
<Alter>45</Alter>
<Adresse Ort="Aachen" Strasse="Gasse 1"></Adresse>
</Person>

Listing 14.69 Konsolenausgabe des Listings 14.68

Ändern Sie die Ausgabeanweisung in der Weise ab, dass Sie das XElement element in eine Zeichenfolge konvertieren. Das ist möglich, weil die Klasse XElement eine ganze Reihe expliziter Typumwandlungen definiert, unter anderem auch in string:

Console.WriteLine((string)element);

Nun werden nur noch die Werte der Elemente angezeigt, also:

FischerManfred45

Übergeben Sie der Methode Element einen Bezeichner, der nicht im XML-Dokument gefunden wird, ist der Rückgabewert null.

Die Methode »Elements«

Gehen wir nun einen Schritt weiter. Wie Sie dem XML-Dokument entnehmen können, sind unterhalb des Stammelements drei Person-Elemente und ein Kunde-Element angeordnet. Uns interessieren jetzt ausschließlich die Person-Elemente, aber nicht das Kunde-Element. Hier hilft uns die Methode Elements weiter, die im Gegensatz zu Element nicht nur das erste, sondern alle übereinstimmenden Elemente zurückliefert. Der Rückgabewert ist vom Typ IEnumerable<XElement>. Sie können die Methode parameterlos aufrufen oder ein Element vom Typ XName übergeben (oder, wie im Abschnitt zuvor bereits erwähnt, eine Zeichenfolge). Die Liste der Person-Elemente erhalten wir mit den folgenden Anweisungen:

XElement root = XElement.Load(@"..\..\Personen.xml");
IEnumerable<XElement> elements = root.Elements("Person");
foreach (XElement item in elements)
Console.WriteLine(item);

Listing 14.70 Elemente filtern mit der Methode »Elements«

Die Anzeige an der Konsole gibt uns alle Person-Elemente einschließlich der untergeordneten Elemente aus.

<Person>
<Name>Fischer</Name>
<Vorname>Manfred</Vorname>
<Alter>45</Alter>
<Adresse Ort="Aachen" Strasse="Gasse 1"></Adresse>
</Person>
[...]
<Person>
<Name>Schmidt</Name>
<Vorname>Detlef</Vorname>
<Alter>28</Alter>
<Adresse Ort="Bonn" Strasse="Weg 34"></Adresse>
</Person>

Listing 14.71 Ausgabe des Listings 14.70

Die Methode Elements lässt sich auch parameterlos aufrufen, also:

XElement root = XElement.Load(@"..\..\Personen.xml");
IEnumerable<XElement> elements = root.Elements();

Es werden daraufhin alle Elemente angezeigt, die dem Element untergeordnet sind, auf dem die Methode aufgerufen wird.

<Person> ... </Person>

<Kunde> ... </Kunde>

<Person> ... </Person>

<Person> ... </Person>

Die Methode »Attribute«

Das Element Adresse hat mit Ort und Strasse zwei Attribute. Wir wollen nun in Erfahrung bringen, welcher Wert sich hinter dem Attribut Strasse des ersten Elements verbirgt. Dazu navigieren wir zum ersten Person-Element und von dort aus zum Element Adresse. Auf dessen Referenz rufen wird die Methode Attribut auf und geben dabei den Attributbezeichner an. Genauso wie die Methode Element liefert uns Attribut das erste passende Element. Wird kein übereinstimmendes Element gefunden, ist der Rückgabewert auch in diesem Fall null.

XElement root = XElement.Load(@"..\..\Personen.xml");
XElement element = root.Element("Person");
XElement address = element.Element("Adresse");
XAttribute attr = address.Attribute("Strasse");
Console.WriteLine(attr);

Listing 14.72 Attribute mit der Methode »Attribute« auswerten

Aus dem Code resultiert die folgende Konsolenausgabe:

Strasse="Gasse 1"

Die Methode »Descendants«

Die Methode Descendants (Nachfahren) ermittelt alle Elemente, die einem bestimmten Knoten untergeordnet sind. Wir wollen uns die Methode Descendants wieder am Beispiel unseres XML-Dokuments ansehen. Unser Ziel sei es, alle Elemente zu finden, die dem ersten Person-Element untergeordnet sind.

XElement root = XElement.Load(@"..\..\Personen.xml");
XElement element = root.Element("Person");
IEnumerable<XElement> elements = element.Descendants();
foreach (XElement item in elements)
Console.WriteLine(item);

Listing 14.73 Nachfahren ermitteln mit der Methode »Descendants« (1)

Weil wir durch den Aufruf der Methode Element zum ersten passenden Person-Element navigieren, wird die Ausgabe wie folgt lauten:

<Name>Fischer</Name>
<Vorname>Manfred</Vorname>
<Alter>45</Alter>
<Adresse Ort="Aachen" Strasse="Gasse 1"></Adresse>

Listing 14.74 Ausgabe des Listings 14.73

Vergleichen Sie diese Ausgabe mit der sehr ähnlichen der Methode Element: Das aktuelle Element ist nicht Bestandteil der Ergebnismenge.

Sie können der Methode Descendants auch ein XName-Objekt übergeben. Die Methode liefert dann alle untergeordneten Elemente, die dem mit XName beschriebenen Element entsprechen. Vielleicht interessieren Sie sich für sämtliche Namen im Dokument. Hier sind dazu die Anweisungen:

XElement root = XElement.Load(@"..\..\Personen.xml");
IEnumerable<XElement> elements = root.Descendants("Name");
foreach (XElement item in elements)
Console.WriteLine((string)item);

Listing 14.75 Nachfahren ermitteln mit der Methode »Descendants« (2)

Da die Laufvariable item in einen String umgewandelt wird, lautet die Ausgabe:

Fischer
Tollsoft AG
Meier
Schmidt

Die Methode »Ancestors«

Mit der Methode Descendants suchen Sie nach Elementen, die weiter im Inneren eines XML-Dokuments, also untergeordnet sind. Die Methode Ancestors (Vorfahren) arbeitet in exakt entgegengesetzter Richtung: Sie sucht nach übereinstimmenden Elementen oberhalb des aktuellen Knotens.

Nachdem wir bisher gesehen haben, wie wir mit verschiedenen Methoden der Klasse XElement innerhalb eines XML-Dokuments navigieren können, wollen wir die Methode Ancestors dazu benutzen, endlich einen LINQ-Ausdruck zu verwenden, um ein bestimmtes Ziel bei der Auswertung zu erreichen. Es sollen uns dabei die Daten interessieren, die die Person mit dem Namen Meier beschreiben.

XElement root = XElement.Load(@"..\..\Personen.xml");

// Nach der Person 'Meier' suchen

XElement person = root.Descendants("Name")
.Where(pers => (string)pers == "Meier")
.First();

// Den Knoten 'Person' des gefundenen Elements referenzieren

var elemts = person.Ancestors("Person");

// Alle Elemente abfragen

foreach(var item in elemts.Elements())

// Prüfen, ob das aktuelle Element Attribute hat

if (item.HasAttributes){

// Liste aller Attribute abfragen

foreach (var temp in item.Attributes())
Console.WriteLine((string) temp);
}
else
Console.WriteLine((string)item);

Listing 14.76 LINQ-Ausdruck zur Filterung eines bestimmten Elements

Nach dem Laden des XML-Dokuments mit der Methode Load suchen wir mit Descendants alle Name-Elemente im Dokument. Mit der Erweiterungsmethode Where filtern wir alle Personen aus der Menge, die Meier heißen. Mit der Erweiterungsmethode First wird sichergestellt, dass jedoch nur eine Person namens Meier das Ergebnis bildet. Dabei handelt es sich um die zuerst gefundene Person.

Da Name nur eines von mehreren datenbeschreibenden Elementen ist, müssen wir mit Ancestors in der Dokumentstruktur eine Ebene höher gehen, um das dazugehörige Person-Element zu referenzieren. Die Methode Elements gestattet es dann, auf das gefundene Person-Element alle untergeordneten Elemente mit Elements abzurufen. Dabei kommt erschwerend hinzu, dass eines der untergeordneten Elemente Attribute hat, die ebenfalls ausgewertet werden müssen. Daher prüfen wir die Elemente mit HasAttributes dahingehend, ob durch das aktuelle Element auch Attribute beschrieben werden. Sollte das der Fall sein, durchlaufen wir diese in einer Schleife. Die Liste aller Attribute stellt uns die Methode Attributes zur Verfügung.

Die Codefragmente zur Navigation finden Sie auf der Buch-DVD innerhalb des Beispielprogramms NavigationSamples.


Galileo Computing - Zum Seitenanfang

14.10.6 Änderungen am XML-Dokument vornehmenZur nächsten ÜberschriftZur vorigen Überschrift

Sicherlich werden Sie nicht nur ein XML-Dokument einlesen, sondern es darüber hinaus auch bearbeiten wollen. Dazu zählt sowohl das Ändern vorhandener Daten als auch das Hinzufügen oder Löschen vorhandener Elemente.

Editieren eines XML-Dokuments

Um den Wert eines bestimmten Elements zu ändern, müssen wir es zunächst einmal referenzieren. Angenommen, die Altersangabe des Herrn Schmidt in unserem Dokument sei deutlich zu jung ausgefallen, und wir müssen es ändern. Dazu müssen wir Herrn Schmidt zunächst im XML-Dokument ausfindig machen, ehe wir die Anpassung vornehmen können.

Zur Änderung eines Elements dient die Methode SetElementValue. Zur Änderung muss der Aufruf auf dem übergeordneten Element erfolgen. SetElementValue erwartet zwei Parameter: Der erste beschreibt ein XName-Objekt, der zweite ist vom Typ Object. Das XName-Objekt kann durch den Bezeichner des zu ändernden Elements beschrieben werden, der zweite Parameter erwartet den neuen Wert.

Das folgende Listing zeigt, wie Sie das zu ändernde Element aufspüren und ändern können.

XElement root = XElement.Load(@"D:\Personen.xml");
XElement name = root.Descendants("Name")
.Where(pers => (string)pers == "Fischer")
.First();
XElement person = name.Parent;
person.SetElementValue("Alter", 18);

Listing 14.77 Ändern eines Elements mit »SetElementValue«

Wie schon im letzten Beispielcode suchen wir zuerst den Eintrag Fischer im XML-Dokument. Im nächsten Schritt muss das direkt übergeordnete Element referenziert werden. Die im letzten Abschnitt vorgestellte Methode Ancestors ist dazu wenig geeignet, da sie uns eine Liste liefert, in der anschließend ein erneuter Suchvorgang ausgeführt werden müsste. Deutlich besser eignet sich die Eigenschaft Parent, die das direkt übergeordnete XElement liefert, also die Referenz auf das <Person>-Element des Herrn Fischer. Darauf wird die SetElementValue-Methode aufgerufen.

Hinzufügen eines Elements

Zum Hinzufügen von Elementen stehen Ihnen mehrere Möglichkeiten zur Verfügung. Zuerst seien die Methoden Add, AddAfterSelf, AddBeforeSelf und AddFirst genannt. Diese werden durch das XElement-Objekt zur Verfügung gestellt. Dabei wird AddBeforeSelf das neue Element vor dem aktuell referenzierten Element einfügen, AddAfterSelf nach dem aktuell referenzierten Element – jeweils auf derselben Strukturebene. AddFirst hingegen fügt das neue Element als erstes untergeordnetes Element ein, Add als letztes aller untergeordneten. Allen vier Methoden übergeben Sie das neue Element als XElement-Objekt, z. B.:

person.Add(new XElement("Telefon", 12345));

Sie können aber auch die im vorigen Abschnitt vorgestellte Methode SetElementValue zum Hinzufügen eines neuen untergeordneten Elements einsetzen. Übergeben Sie dazu dem ersten Parameter ein XName-Objekt (oder eine entsprechende Zeichenfolge), das namentlich nicht als untergeordnetes Element erkannt wird, wird das XName-Objekt als neu hinzuzufügendes Element interpretiert.

Genauso soll es nun dem einzigen Kunden in unserem Dokument ergehen.

XElement root = XElement.Load(@"D:\Personen.xml");
XElement name = root.Descendants("Name")
.Where(pers => (string)pers == "Tollsoft AG")
.First();
XElement person = name.Parent;
person.SetElementValue("Telefon", 123456);

Listing 14.78 Hinzufügen eines Elements mit »SetElementValue«

Löschen eines Elements

Auch zum Löschen eines Elements werden von der Klasse XElement mehrere Methoden angeboten (z. B. Remove, RemoveAll, RemoveAttribute). Da uns die Methode SetElementValue aber bereits sehr vertraut geworden ist, wollen wir sie dazu benutzen. Sie müssen dazu nur im zweiten Parameter null übergeben. Das ist bereits alles.

Um das noch zuvor zugestandene Element für die Telefonnummer des Kunden wieder zu entfernen, genügt die folgende Anweisung:

person.SetElementValue("Telefon", null);


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# 2012

Visual C# 2012
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 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.


[Rheinwerk Computing]

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