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.3 Die Klasse »XmlReader« Zur nächsten ÜberschriftZur vorigen Überschrift


Galileo Computing - Zum Seitenanfang

16.3.1 XML-Dokumente mit einem »XmlReader«-Objekt lesen Zur nächsten ÜberschriftZur vorigen Überschrift

Das .NET Framework bietet mehrere Möglichkeiten, um die von einem XML-Dokument beschriebenen Daten zu lesen. In diesem Abschnitt wollen wir uns mit der einfachsten Variante beschäftigen, nämlich dem Einlesen über ein XmlReader-Objekt.

Ein Objekt vom Typ XmlReader liest die Elemente eines XML-Dokuments einzeln und der Reihe nach einmal ein. Die gelesenen Daten sind schreibgeschützt und bleiben nicht im Arbeitsspeicher. Das mag ein Nachteil sein, hat aber auch zur Folge, dass die Speicherressourcen geschont werden und der Lesevorgang schnell ist. Damit bietet sich die Klasse XmlReader besonders an, wenn es ausreicht, ein XML-Dokument nur sequenziell zu lesen, und Sie nicht innerhalb des Dokuments nach bestimmten Daten suchen wollen. Die Klasse ist als abstract definiert und kann demnach nicht instanziiert werden. Allerdings bietet die Klasse mit der statischen Methode Create die Möglichkeit, sich eine Instanz zu besorgen.


XmlReader reader = XmlReader.Create(@"MeineDaten.xml");

Beachten Sie bitte, dass Sie den Namespace System.Xml mit using bekannt geben sollten.


Anmerkung

Im .NET Framework 1.x übernahm die Klasse XmlTextReader die Aufgabe, ein XML-Dokument einzulesen. Seit der Veröffentlichung von .NET 2.0 wird empfohlen, dafür die Klasse XmlReader und deren Methode Create einzusetzen, da XmlReader mehr Möglichkeiten bietet als XmlTextReader.


Nachdem Sie das XmlReader-Objekt erzeugt haben, rufen Sie in einer Schleife die Methode Read auf, die alle Knoten im XML-Dokument nacheinander abruft. Der Rückgabewert der Methode ist true, wenn noch mindestens ein weiterer Knoten eingelesen werden kann.


while(reader.Read())
{
  // weitere Anweisungen
}

In der Schleife muss zuerst untersucht werden, welcher Knoten aktuell gelesen wird. Hier interessieren vorrangig Typ und Name des Knotens. Den Typ des Knotens rufen Sie mit der Eigenschaft NodeType ab, die durch einen Wert der Enumeration XmlNodeType beschrieben wird. Tabelle 16.2 beschreibt einen Auszug aus dieser Enumeration.


Tabelle 16.2 Auszug aus der Enumeration »XmlNodeType«

Bezeichner Beschreibung

Element

Beschreibt ein Element, z. B. <Artikel>.

Attribute

Beschreibt ein Attribut.

Text

Beschreibt den Textinhalt eines Knotens.

CDATA

Beschreibt einen CDATA-Abschnitt.

ProcessingInstruction

Beschreibt eine Verarbeitungsanweisung, z. B.
<?pi Testanweisung?>
.

Comment

Beschreibt einen Kommentar, z. B.
<!-- Ich bin ein Kommentar -->
.

Whitespace

Beschreibt Leerraum zwischen Markup.

EndElement

Beschreibt ein Endelement-Tag, z. B. </Artikel>.

XmlDeclaration

Beschreibt die XML-Deklaration, z. B. <?xml version='1.0'?>.


Die Struktur einer Schleife könnte also wie folgt codiert sein:


while (reader.Read()) {
  switch (reader.NodeType) {
    case XmlNodeType.XmlDeclaration: 
      // Anweisungen
      break;
    case XmlNodeType.CDATA: 
      // Anweisungen
      break;
    ...
  }
}

Der Untersuchung des Knotentyps hat eine besondere Bedeutung hinsichtlich der Auswertung, denn je nach Typ möchten Sie entweder den Knotenbezeichner oder den von einem Knoten beschriebenen Inhalt auswerten. Dazu dienen die beiden Eigenschaften Name und Value des XmlReader-Objekts.

Mit Value rufen Sie den Inhalt des aktuellen Knotens ab. Von den in Tabelle 16.2 angeführten Knotentypen können nur Attribute, CDATA, Comment, ProcessingInstruction, Text, Whitespace und XmlDeclaration einen Wert zurückgeben. Alle anderen Knoten liefern String.Empty.

Die Eigenschaft Name hingegen liefert den Bezeichner des aktuellen Knotens. Auch diese Eigenschaft ist auf bestimmte Knotentypen beschränkt. Dazu gehören Attribute, Element, EndElement, ProcessingInstruction und XmlDeclaration.

Attribute eines Elements auswerten

Eine spezielle Behandlung erfahren die Attribute eines Knotens vom Typ XmlNodeType.Element. Eigentlich würde man erwarten, dass ein Attribut als Knoten erkannt wird und dass das XmlReader-Objekt sich bei jedem Aufruf von Read auch von Attribut zu Attribut hangelt. Tatsächlich aber liest der XmlReader ein XmlNodeType.Element samt dessen Attributen komplett ein, sodass die Attribute beim nächsten Aufruf der Read-Methode nicht mehr im Datenstrom enthalten sind. Sie haben dann zwar den Inhalt des Elements ausgewertet, aber die Attribute unberücksichtigt gelassen.

Ist nicht exakt bekannt, ob und wie viele Attribute ein Element hat, hilft Ihnen die Eigenschaft HasAttributes des XmlReader-Objekts weiter, die true oder false zurückliefert. Diese Eigenschaft wird aufgerufen, wenn es sich bei dem aktuellen Knoten um den Typ XmlNodeType.Element handelt. Mit der Eigenschaft AttributeCount lässt sich die Anzahl der Attribute in Erfahrung bringen. Den zurückgelieferten Wert können Sie in einer for-Schleife verwenden. Die Methode GetAttribute unter Angabe entweder des Index oder des Attributbezeichners liefert den Wert des Attributs.


...
case XmlNodeType.Element:
  if (reader.HasAttributes) {
    for (int i = 0; i < reader.AttributeCount; i++) {
      Console.WriteLine(reader.GetAttribute(i));
    }
  }
  break;
...

Alternativ können Sie auch mit der Methode MoveToNextAttribute durch die Liste der Attribute navigieren. Ähnlich der Read-Methode des XmlReader-Objekts liefert auch diese Methode true zurück, falls das Element noch ein weiteres Attribut enthält.


...
case XmlNodeType.Element:
  if (reader.HasAttributes) {
    while (reader.MoveToNextAttribute()) {
      // Anweisungen
    }
  }
  break;
...

Beispielprogramm

Wir wollen uns nun die bisherigen Erkenntnisse in einem kompletten Beispielprogramm ansehen. Dazu brauchen wir eine XML-Datei. Um nicht nur die XML-Datei, sondern auch deren Analyse und Ausgabe nicht zu aufwendig zu gestalten, wird mit dem Dokument nur eine Person mit den wichtigsten Eckdaten beschrieben.


<?xml version="1.0" encoding="utf-8" ?>
<!-- Liste von Personen-->
<Personen>
  <Person>
    <Befehl><![CDATA[Ich stehe unter CDATA]]></Befehl>
    <Vorname>Manfred</Vorname>
    <Telefon/>
    <Zuname>Fischer</Zuname>
    <Alter>45</Alter>
    <Adresse Ort="Bonn" Strasse="Neuestr.34"></Adresse>
  </Person>
</Personen>

Auf eine genaue Erklärung des folgenden Codings werde ich an dieser Stelle verzichten. Er erhält ausschließlich Passagen, die bereits zuvor erläutert worden sind. Sie sollten den Code jedoch einmal mit der Konsolenausgabe vergleichen, die Sie in Abbildung 16.5 sehen.


// ---------------------------------------------------------
// Beispiel: ...\Kapitel 16\XmlReaderSample
// ---------------------------------------------------------
XmlReader reader = XmlReader.Create(@"..\..\Personen.xml");
while (reader.Read()) {
  switch (reader.NodeType) {
   case XmlNodeType.XmlDeclaration:
     Console.WriteLine("{0,-20}<{1}>", "DEKLARATION", reader.Value);
     break;
   case XmlNodeType.CDATA:
     Console.WriteLine("{0,-20}{1}", "CDATA", reader.Value);
     break;
   case XmlNodeType.Whitespace:
     Console.WriteLine("{0,-20}","WHITESPACE");
     break;
   case XmlNodeType.Comment:
     Console.WriteLine("{0,-20}<!--{1}-->","COMMENT", reader.Value);
     break;
   case XmlNodeType.Element:
     if (reader.IsEmptyElement)
       Console.WriteLine("{0,-20}<{1} />","EMPTY_ELEMENT", reader.Name);
     else {
       Console.WriteLine("{0,-20}<{1}>", "ELEMENT", reader.Name); 
       // prüfen, ob der Knoten Attribute hat
       if (reader.HasAttributes) {
         // Durch die Attribute navigieren
         while (reader.MoveToNextAttribute()) {
           Console.WriteLine("{0,-20}{1}", 
                  "ATTRIBUT", reader.Name + "=" + reader.Value);
         }
       }
     }
     break;
   case XmlNodeType.EndElement:
     Console.WriteLine("{0,-20}</{1}>", "END_ELEMENT", reader.Name);
     break;
   case XmlNodeType.Text:
     Console.WriteLine("{0,-20}{1}", "TEXT", reader.Value);
     break;
  }            
}

Abbildung 16.5 Ausgabe des Beispielprogramms »XmlReaderSample«

Daten eines XML-Dokuments verarbeiten

Das folgende Beispiel zeigt, wie die Daten dazu benutzt werden können, Objekte zu erstellen, die die gelesenen Daten in einem sinnvollen Kontext speichern. Ausgangspunkt sei wieder eine XML-Datei, die in diesem Fall aber nicht nur eine, sondern mehrere Personen beschreibt. Eine Person sei durch Vorname, Zuname, Alter sowie eine Adresse beschrieben.


<Person>
  <Vorname>Manfred</Vorname>
  <Zuname>Fischer</Zuname>
  <Alter>45</Alter>
  <Adresse Ort="Bonn" Strasse="Neuestr.34"></Adresse>
</Person>

Die Daten zu einer Person sollen in einem Objekt vom Typ Person gespeichert werden. Für die Angaben der Adresse einer Person steht eine weitere Klasse Adresse zur Verfügung, die mit Ort und Strasse zwei Eigenschaften hat.


// ---------------------------------------------------------
// Beispiel: ...\Kapitel 16\UsingXmlData
// ---------------------------------------------------------
static void Main(string[] args) {
  XmlReader reader;
  reader = XmlReader.Create(@"..\..\Personen.xml");
  List<Person> liste = new List<Person>();
  Person person = null;
  Adresse adresse = null;
  while (reader.Read()) {
    // prüfen, ob es sich aktuell um ein Element handelt
    if (reader.NodeType == XmlNodeType.Element) {
      // alle relevanten Elemente untersuchen
      switch(reader.Name) {
        case "Person":
          // neue Person erzeugen und in Liste eintragen
          person = new Person();
          liste.Add(person);
          break;
        case "Vorname":
          person.Vorname = reader.ReadString();   
          break;
        case "Zuname":
          person.Zuname = reader.ReadString();   
          break;
        case "Alter":
          person.Alter = reader.ReadElementContentAsInt(); 
          break;
        case "Adresse":
          // neue Adresse erzeugen und der Person zuordnen
          adresse = new Adresse();
          person.Adresse = adresse;
          if (reader.HasAttributes) {
            // Attributsliste durchlaufen
            while (reader.MoveToNextAttribute())
            {
              if (reader.Name == "Ort")
                adresse.Ort = reader.Value;
              else if (reader.Name == "Strasse")
                adresse.Strasse = reader.Value;
            }
          }
          break;
      }
    }
  }
  // Liste an der Konsole ausgeben
  GetList(liste);
  reader.Close();
  Console.ReadLine();
}
// Ausgabe der Listeneinträge
static void GetList(List<Person> liste) {
  foreach (Person temp in liste)
  {
    Console.WriteLine("Vorname: {0}\nZuname: {1}\nAlter: {2}",
            temp.Vorname, temp.Zuname, temp.Alter);
    Console.WriteLine("Ort: {0}\nStrasse: {1}\n", 
            temp.Adresse.Ort, temp.Adresse.Strasse);
  }
}

In der while-Schleife interessieren im Zusammenhang mit der Aufgabenstellung nur die Elemente, die Daten beschreiben. Trifft der Reader auf einen Knoten vom Typ XmlNodeType.Element, wird mit einer switch-Anweisung der Elementbezeichner ausgewertet. In den case-Zweigen wird der beschriebene Wert des Elements ermittelt und der entsprechenden Eigenschaft eines Person-Objekts zugewiesen, das beim Erreichen des Elements Person erzeugt und einer generischen Liste hinzugefügt wird. Trifft die Laufzeit auf das Element Adresse, wird ein Objekt der gleichnamigen Klasse erzeugt und die Liste der Attribute des Elements ausgewertet.

Den vollständigen Code einschließlich der Klassen Person und Adresse finden Sie auf der Buch-DVD.


Galileo Computing - Zum Seitenanfang

16.3.2 Validieren eines XML-Dokuments topZur vorigen Überschrift

Die XML-Dokumente in den beiden zuvor gezeigten Beispielprogrammen sind wohlgeformt. Sie erkennen das daran, dass die gesamte Datei eingelesen wird, ohne dass es zu einer Ausnahme vom Typ XmlException kommt. Das bedeutet aber noch nicht, dass das Dokument valide, also gültig ist. Wie Sie wissen, ist dazu eine XML-Schema-Datei erforderlich. Mit dem Tool xsd.exe oder Visual Studio ist eine solche Datei sehr einfach zu erzeugen.

Um ein XML-Dokument, das mit einem XmlReader-Objekt sequenziell eingelesen wird, zu validieren, müssen wir auf eine Überladung der Methode Create der Klasse XmlReader zurückgreifen, die in einem zweiten Parameter nach einem Objekt vom Typ XmlReaderSettings verlangt.


public static XmlReader Create(string, XmlReaderSettings)

Ein XmlReaderSettings-Objekt dient nicht nur dazu, die Validierung vorzuschreiben. Es kann darüber hinaus das XmlReader-Objekt mit spezifischen Eigenschaften ausstatten. Beispielsweise könnte das XmlReaderSettings-Objekt das Einlesen der Kommentare oder die Berücksichtigung der Whitespaces unterbinden.

Doch widmen wir uns hier der Validierung. Zunächst müssen wir die Klasse XmlReaderSettings instanziieren und anschließend die Eigenschaft ValidationType einstellen. Wollen wir das Dokument gegen ein XML Schema auf Gültigkeit prüfen, müssen wir ValidationType.Schema angeben, z. B.:


XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.ValidationType = ValidationType.Schema;

Im nächsten Schritt ist das XML Schema zu benennen. Da es sich auch um mehrere Schemas handeln könnte, kommt eine Auflistung ins Spiel, der alle XML Schemas hinzugefügt werden. Die Referenz auf diese Auflistung erhalten wir über die Eigenschaft Schemas des XmlReaderSettings-Objekts. Darauf rufen wir die Methode Add auf, die im ersten Parameter den im Schema angegebenen targetNamespace erwartet. Enthält das XML Schema kein Attribut targetNamespace oder legen Sie auf den Namespace der im XML Schema beschriebenen Elemente keinen Wert, können Sie dem ersten Parameter auch null übergeben. Dem zweiten Parameter teilen Sie den URI der XML-Schema-Datei mit.


readerSettings.Schemas.Add(null, @"..\..\Personen.xsd");

Sollte bei der Validierung des XML-Dokuments ein Fehler auftreten, wird das XmlReaderSettings-Objekt das Ereignis ValidationEventHandler auslösen. Wir müssen bei dem Objekt jetzt nur noch einen passenden Ereignishandler registrieren.

readerSettings.ValidationEventHandler += ValidationCallback;

Scheitert die Validierung, wird die Überprüfung des XML-Dokuments abgebrochen. Der Rest des Dokuments wird zwar weiterhin eingelesen, bleibt aber ungeprüft, und folgende Validierungsfehler werden nicht mehr erkannt. Besser ist es, im Fall des Scheiterns der Validierung eine Ausnahme auszulösen. Dies ermöglicht uns der Parameter vom Typ ValidationEventArgs des Ereignishandlers, der drei spezifische Eigenschaften hat, die Sie der Tabelle 16.3 entnehmen können.


Tabelle 16.3 Die Eigenschaften des »ValidationEventArgs«-Objekts

Eigenschaft Beschreibung

Exception

Ruft die dem Validierungsfehler zugeordnete Excpetion vom Typ XmlSchemaException ab.

Message

Liefert eine textuelle Beschreibung des aufgetretenen Validierungsfehlers.

Severity

Ruft den Schweregrad des Validierungsfehlers ab. Dabei werden zwei Schweregrade unterschieden: Warning, falls kein XML Schema vorhanden ist, anhand dessen validiert werden kann, und Error, wenn ein Validierungsfehler auftritt.


Bitte beachten Sie, dass die Klasse ValidationEventArgs im Namespace System.Xml.Schema enthalten ist, der über using bekannt gegeben werden sollte.

Nachdem nun alle vorbereitenden Maßnahmen ergriffen worden sind, müssen wir zum Schluss noch dem XmlReader-Objekt das konfigurierte XmlReaderSettings-Objekt übergeben.


XmlReader reader = 
    XmlReader.Create(@"..\..\Personen.xml", readerSettings);

Beispielprogramm zur Validierung

Die XML-Datei aus dem Beispiel XmlReaderSample soll nun anhand eines XML- Schemas validiert werden. Tritt ein Validierungsfehler auf, soll eine Ausnahme ausgelöst werden, die wir dem zweiten Parameter des Ereignishandlers entnehmen.

Darüber hinaus interessieren uns in der Ausgabe weder die Kommentare noch die Whitespaces. Diese werden durch die Einstellungen IgnoreWhitespace und IgnoreComments des XmlReaderSettings-Objekts ignoriert.


// ---------------------------------------------------------
// Beispiel: ... \Kapitel 16\ValidationSample
// ---------------------------------------------------------
static void Main(string[] args) {
  XmlReaderSettings readerSettings = new XmlReaderSettings();
  readerSettings.IgnoreWhitespace = true;
  readerSettings.IgnoreComments = true;
  readerSettings.ValidationType = ValidationType.Schema;
  readerSettings.Schemas.Add(null, @"..\..\Personen.xsd");
  readerSettings.ValidationEventHandler += ValidationCallback;
  XmlReader reader = XmlReader.Create(@"..\..\Personen.xml", readerSettings);
  try {
    while (reader.Read()) {
      // Code wie im Beispielprogramm "XmlReaderSample"
    }
  }
  catch(Exception ex) {
    Console.WriteLine("Validierung fehlgeschlagen. \n{0}", ex.Message);
  }
  reader.Close();
  Console.ReadLine();
}
// Ereignishandler
static void ValidationCallback(object sender, ValidationEventArgs e)
{
  throw e.Exception;
}

Die XSD-Datei zu diesem Beispielprogramm liegt im Verzeichnis der Sourcecode-Dateien. Die Validierung wird zunächst ergeben, dass das XML-Dokument wohlgeformt und gültig ist. Sie können, um eine fehlgeschlagene Validierung zu simulieren, in der XML-Schema-Datei beispielsweise das Element Befehl in Befehl1 ändern.



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