Klasse „System.Xml.Serialization.XmlSerializer“

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Die XML-Serialisierung ist die Konvertierung der öffentlichen Eigenschaften und Felder eines Objekts in ein serielles Format (in diesem Fall XML) zum Zweck der Speicherung und Übermittlung. Die Deserialisierung erstellt das Objekt aus der XML-Ausgabe in seinem ursprünglichen Zustand erneut. Sie können sich die Serialisierung als Möglichkeit zum Speichern des Zustands eines Objekts in einem Stream oder Puffer vorstellen. Beispielsweise verwendet ASP.NET die Klasse XmlSerializer zum Codieren von XML-Webdienstnachrichten.

Die Daten des Objekts werden durch Konstrukte der Programmiersprache beschrieben, z. B. Klassen, Felder, Eigenschaften, primitive Typen, Arrays oder auch eingebettetes XML in Form von XmlElement-Objekten oder XmlAttribute-Objekten. Sie können eigene, mit Attributen versehene Klassen erstellen oder die Klassen mit dem Tool für die XML-Schemadefinition (Xsd.exe) auf der Grundlage eines vorhandenen Dokuments für die XML-Schemadefinition (XSD) generieren. Wenn ein XML-Schema gegeben ist, können Sie Xsd.exe ausführen und so eine Reihe von Klassen erstellen, die für dieses Schema streng typisiert und mit Attributen versehen sind, damit bei der Serialisierung das Schema eingehalten wird.

Zum Übertragen von Daten zwischen Objekten und XML ist eine Zuordnung zwischen den Programmiersprachenkonstrukten und dem XML-Schema sowie zwischen dem XML-Schema und den Programmiersprachenkonstrukten erforderlich. XmlSerializer und damit verbundene Tools wie Xsd.exe stellen die Brücke zwischen diesen beiden Technologien sowohl zur Entwurfszeit als auch zur Laufzeit dar. Verwenden Sie zur Entwurfszeit Xsd.exe, um ein XML-Schemadokument (.xsd) aus Ihren benutzerdefinierten Klassen oder Klassen aus einem bestimmten Schema zu erstellen. In beiden Fällen werden die Klassen mit benutzerdefinierten Attributen versehen, um XmlSerializer anzuweisen, wie die Zuordnung zwischen dem XML-Schemasystem und der Common Language Runtime erfolgen soll. Zur Laufzeit können Instanzen der Klassen in XML-Dokumente serialisiert werden, die dem angegebenen Schema entsprechen. Ebenso können diese XML-Dokumente in Laufzeitobjekte deserialisiert werden. Beachten Sie, dass das XML-Schema optional ist und zur Entwurfszeit oder Laufzeit nicht erforderlich ist.

Steuern der generierten XML

Um die generierte XML zu steuern, können Sie spezielle Attribute auf Klassen und Member anwenden. Wenn Sie beispielsweise einen anderen XML-Elementnamen angeben möchten, wenden Sie XmlElementAttribute auf ein öffentliches Feld oder eine Eigenschaft an, und legen Sie die ElementName-Eigenschaft fest. Eine vollständige Liste ähnlicher Attribute finden Sie unter Attribute zur Steuerung der XML-Serialisierung. Sie können auch die IXmlSerializable-Schnittstelle implementieren, um die XML-Ausgabe zu steuern.

Wenn die generierte XML Abschnitt 5 des World Wide Consortium-Dokuments (Simple Object Access-Protokoll (SOAP) 1.1) entsprechen muss, müssen Sie XmlSerializer mit XmlTypeMapping erstellen. Um die codierte SOAP-XML weiter zu steuern, verwenden Sie die unter Attribute zur Steuerung der Serialisierung von codiertem SOAP aufgeführten Attribute.

Mit XmlSerializer können Sie stark typisierte Klassen nutzen und dennoch von der Flexibilität von XML profitieren. Wenn Sie Felder oder Eigenschaften des Typs XmlElement, XmlAttribute oder XmlNode in Ihren stark typisierten Klassen verwenden, können Sie Teile des XML-Dokuments direkt in XML-Objekte einlesen.

Wenn Sie mit erweiterbaren XML-Schemas arbeiten, können Sie auch die Attribute XmlAnyElementAttribute und XmlAnyAttributeAttribute zum Serialisieren oder Deserialisieren von Elementen oder Attributen verwenden, die im ursprünglichen Schema nicht enthalten sind. Um die Objekte zu verwenden, wenden Sie XmlAnyElementAttribute auf ein Feld an, das ein Array von XmlElement-Objekten zurückgibt, oder wenden Sie XmlAnyAttributeAttribute auf ein Feld an, das ein Array von XmlAttribute-Objekten zurückgibt.

Wenn eine Eigenschaft oder ein Feld ein komplexes Objekt zurückgibt (z. B. ein Array oder eine Klasseninstanz), wird dieses von XmlSerializer in ein Element konvertiert, das innerhalb des XML-Hauptdokuments geschachtelt ist. Die erste Klasse im folgenden Code gibt beispielsweise eine Instanz der zweiten Klasse zurück.

Public Class MyClass
    Public MyObjectProperty As MyObject
End Class

Public Class MyObject
    Public ObjectName As String
End Class
public class MyClass
{
    public MyObject MyObjectProperty;
}
public class MyObject
{
    public string ObjectName;
}

Die serialisierte XML-Ausgabe sieht wie folgt aus:

<MyClass>
  <MyObjectProperty>
  <ObjectName>My String</ObjectName>
  </MyObjectProperty>
</MyClass>

Wenn ein Schema ein optionales Element (minOccurs = '0') oder einen Standardwert enthält, haben Sie zwei Optionen. Eine Option besteht darin, System.ComponentModel.DefaultValueAttribute zur Angabe des Standardwerts zu verwenden, wie im folgenden Code dargestellt:

Public Class PurchaseOrder
    <System.ComponentModel.DefaultValueAttribute ("2002")> _
    Public Year As String
End Class
public class PurchaseOrder
{
    [System.ComponentModel.DefaultValueAttribute ("2002")]
    public string Year;
}

Eine weitere Option besteht darin, ein spezielles Muster zum Erstellen eines booleschen Felds zu verwenden, das von XmlSerializer erkannt wird, und XmlIgnoreAttribute auf das Feld anzuwenden. Das Muster wird im Format propertyNameSpecified erstellt. Wenn beispielsweise ein Feld mit dem Namen „MyFirstName“ vorhanden ist, erstellen Sie auch ein Feld mit dem Namen „MyFirstNameSpecified“, das XmlSerializer anweist, ob das XML-Element namens „MyFirstName“ generiert werden soll. Dies wird im folgenden Beispiel gezeigt.

Public Class OptionalOrder
    ' This field's value should not be serialized
    ' if it is uninitialized.
    Public FirstOrder As String

    ' Use the XmlIgnoreAttribute to ignore the
    ' special field named "FirstOrderSpecified".
    <System.Xml.Serialization.XmlIgnoreAttribute> _
    Public FirstOrderSpecified As Boolean
End Class
public class OptionalOrder
{
    // This field should not be serialized
    // if it is uninitialized.
    public string FirstOrder;

    // Use the XmlIgnoreAttribute to ignore the
    // special field named "FirstOrderSpecified".
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public bool FirstOrderSpecified;
}

Außerkraftsetzen der Standardserialisierung

Sie können auch die Serialisierung einer beliebigen Objektgruppe und ihrer Felder und Eigenschaften außer Kraft setzen, indem Sie eins der entsprechenden Attribute erstellen und einer Instanz der XmlAttributes-Klasse hinzufügen. Das Außerkraftsetzen der Serialisierung auf diese Weise hat zwei Vorteile: Erstens können Sie die Serialisierung von Objekten in einer DLL steuern und erweitern, auch wenn Sie keinen Zugriff auf die Quelle haben. Zweitens können Sie einen Satz serialisierbarer Klassen erstellen, die Objekte aber auf mehrere Arten serialisieren. Ausführlichere Informationen finden Sie im Artikel zur XmlAttributeOverrides-Klasse und unter Vorgehensweise: Steuern der Serialisierung abgeleiteter Klassen.

Rufen Sie die Serialize-Methode auf, um ein Objekt zu serialisieren. Rufen Sie die Deserialize-Methode auf, um ein Objekt zu deserialisieren.

Informationen zum Hinzufügen von XML-Namespaces zu einem XML-Dokument finden Sie unter XmlSerializerNamespaces.

Hinweis

XmlSerializer wendet eine besondere Behandlung auf Klassen an, die IEnumerable oder ICollection implementieren. Eine Klasse, die IEnumerable implementiert, muss eine öffentliche Add-Methode mit einem einzigen Parameter implementieren. Der Parameter der Add-Methode muss denselben Typ aufweisen, der von der Current-Eigenschaft für den von GetEnumerator zurückgegebenen Wert oder einer der Basiswerte dieses Typs zurückgegeben wird. Eine Klasse, die ICollection (z. B. CollectionBase) zusätzlich zu IEnumerable implementiert, muss eine öffentliche mit Item indizierte Eigenschaft (Indexer in C#), die einen ganzzahligen Wert annimmt, sowie eine öffentliche Count-Eigenschaft vom Typ „Integer“ aufweisen. Der Parameter für die Add-Methode muss vom gleichen Typ sein wie der Wert, den die Item-Eigenschaft zurückgibt, oder muss ein Basistyp dieses Typs sein. Bei Klassen, die ICollection implementieren, werden die zu serialisierenden Werte über die indizierte Item-Eigenschaft und nicht durch einen Aufruf von GetEnumerator abgerufen.

Sie müssen über die Berechtigung zum Schreiben in das temporäre Verzeichnis (gemäß Definition durch die TEMP-Umgebungsvariable) verfügen, um ein Objekt zu deserialisieren.

Dynamisch generierte Assemblys

Um die Leistung zu erhöhen, generiert die XML-Serialisierungsinfrastruktur dynamisch Assemblys zum Serialisieren und Deserialisieren der angegebenen Typen. Die Infrastruktur sucht diese Assemblys und verwendet sie wieder. Dieses Verhalten tritt nur bei Verwendung der folgenden Konstruktoren auf:

XmlSerializer.XmlSerializer(Type)

XmlSerializer.XmlSerializer(Type, String)

Wenn Sie einen der anderen Konstruktoren verwenden, werden mehrere Versionen derselben Assembly generiert und nie entladen, was zu einem Arbeitsspeicherverlust und einer schlechten Leistung führt. Die einfachste Lösung besteht darin, einen der beiden zuvor erwähnten Konstruktoren zu verwenden. Andernfalls müssen Sie die Assemblys in Hashtable zwischenspeichern, wie im folgenden Beispiel gezeigt:

Hashtable serializers = new Hashtable();

// Use the constructor that takes a type and XmlRootAttribute.
XmlSerializer s = new XmlSerializer(typeof(MyClass), myRoot);

// Implement a method named GenerateKey that creates unique keys
// for each instance of the XmlSerializer. The code should take
// into account all parameters passed to the XmlSerializer
// constructor.
object key = GenerateKey(typeof(MyClass), myRoot);

// Check the local cache for a matching serializer.
XmlSerializer ser = (XmlSerializer)serializers[key];
if (ser == null)
{
    ser = new XmlSerializer(typeof(MyClass), myRoot);
    // Cache the serializer.
    serializers[key] = ser;
}

// Use the serializer to serialize or deserialize.
Dim serializers As New Hashtable()

' Use the constructor that takes a type and XmlRootAttribute.
Dim s As New XmlSerializer(GetType([MyClass]), myRoot)

' Implement a method named GenerateKey that creates unique keys
' for each instance of the XmlSerializer. The code should take
' into account all parameters passed to the XmlSerializer
' constructor.
Dim key As Object = GenerateKey(GetType([MyClass]), myRoot)

' Check the local cache for a matching serializer.
Dim ser As XmlSerializer = CType(serializers(key), XmlSerializer)

If ser Is Nothing Then
    ser = New XmlSerializer(GetType([MyClass]), myRoot)
    ' Cache the serializer.
    serializers(key) = ser
End If

' Use the serializer to serialize or deserialize.

Serialisierung von ArrayList und generischer Listen

XmlSerializer kann die folgenden Elemente nicht serialisieren oder deserialisieren:

Serialisierung von Enumerationen von „unsigned long“

XmlSerializer kann nicht zum Serialisieren einer Enumeration instanziiert werden, wenn die folgenden Bedingungen zutreffen: Die Enumeration ist vom Typ „unsigned long“ (ulong in C#), und die Enumeration enthält ein Member mit einem Wert, der größer als 9.223.372.036.854.775.807 ist. Beispielsweise kann Folgendes nicht serialisiert werden:

public enum LargeNumbers: ulong
{
    a = 9223372036854775808
}
// At run time, the following code will fail.
xmlSerializer mySerializer=new XmlSerializer(typeof(LargeNumbers));

Veraltete Typen

Die XmlSerializer Klasse serialisiert keine Objekte, die als [Obsolete]gekennzeichnet sind.