Steuern der XML-Serialisierung mit Attributen

Attribute können verwendet werden, um die XML-Serialisierung eines Objekts zu steuern oder um einen alternativen XML-Stream aus derselben Reihe von Klassen zu erstellen. Weitere Informationen zum Erstellen eines alternativen XML-Streams finden Sie unter Vorgehensweise: Angeben eines alternativen Elementnamens für einen XML-Stream.

Hinweis

Wenn der generierte XML-Stream Abschnitt 5 des vom World Wide Web Consortium (W3C) herausgegebenen Dokument mit dem Titel Simple Object Access Protocol (SOAP) 1.1 entsprechen soll, verwenden Sie die unter Attribute zur Steuerung der Serialisierung von codiertem SOAP aufgeführten Attribute.

Standardmäßig wird der Name eines XML-Elements durch den Klassen- oder Membernamen festgelegt. In einer einfachen Klasse namens Book wird, wie in folgendem Beispiel gezeigt, durch ein Feld mit der Bezeichnung ISBN ein XML-Elementtag <ISBN> erstellt.

Public Class Book
    Public ISBN As String
End Class
' When an instance of the Book class is serialized, it might
' produce this XML:
' <ISBN>1234567890</ISBN>.
public class Book
{
    public string ISBN;
}
// When an instance of the Book class is serialized, it might
// produce this XML:
// <ISBN>1234567890</ISBN>.

Sie können dieses Standardverhalten ändern, wenn Sie das Element umbenennen möchten. Der folgende Code veranschaulicht, wie ein Attribut die Änderung durch das Festlegen der ElementName-Eigenschaft von XmlElementAttribute ermöglicht.

Public Class TaxRates
   < XmlElement(ElementName = "TaxRate")> _
    Public ReturnTaxRate As Decimal
End Class
public class TaxRates {
    [XmlElement(ElementName = "TaxRate")]
    public decimal ReturnTaxRate;
}

Weitere Informationen zu Attributen finden Sie unter Attribute. Eine Liste mit Attributen zur Steuerung der XML-Serialisierung finden Sie unter Attribute zur Steuerung der XML-Serialisierung.

Steuern der Serialisierung von Arrays

Die Attribute XmlArrayAttribute und XmlArrayItemAttribute dienen zum Steuern der Serialisierung von Arrays. Mit diesen Attributen können Sie den Elementnamen, den Namespace und den XSD-Schemadatentyp steuern (wie im vom World Wide Web Consortium [www.w3.org] herausgegebenen Dokument mit folgendem Titel definiert: „XML Schema Part 2: Datatypes“). Sie können auch die Typen angeben, die in einem Array enthalten sein können.

Durch XmlArrayAttribute werden die Eigenschaften des einschließenden XML-Elements bestimmt, das aus der Serialisierung eines Arrays hervorgeht. So wird beispielsweise durch das Serialisieren des unten aufgeführten Arrays standardmäßig ein XML-Element mit der Bezeichnung Employees erzeugt. Das Employees-Element enthält eine Reihe von Elementen, die nach dem Arraytyp Employee benannt sind.

Public Class Group
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
public class Group {
    public Employee[] Employees;
}
public class Employee {
    public string Name;
}

Eine serialisierte Instanz könnte etwa wie folgt aussehen.

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</Employees>
</Group>

Sie können den Namen des XML-Elements wie folgt ändern, indem Sie XmlArrayAttribute anwenden.

Public Class Group
    <XmlArray("TeamMembers")> _
    Public Employees() As Employee
End Class
public class Group {
    [XmlArray("TeamMembers")]
    public Employee[] Employees;
}

Der resultierende XML-Stream könnte wie folgt aussehen.

<Group>
<TeamMembers>
    <Employee>
        <Name>Haley</Name>
    </Employee>
</TeamMembers>
</Group>

Andererseits steuert XmlArrayItemAttribute, wie die im Array enthaltenen Elemente serialisiert werden. Beachten Sie, dass das Attribut auf das Feld angewendet wird, das vom Array zurückgegeben wird.

Public Class Group
    <XmlArrayItem("MemberName")> _
    Public Employee() As Employees
End Class
public class Group {
    [XmlArrayItem("MemberName")]
    public Employee[] Employees;
}

Der resultierende XML-Stream könnte wie folgt aussehen.

<Group>
<Employees>
    <MemberName>Haley</MemberName>
</Employees>
</Group>

Serialisieren von abgeleiteten Klassen

Außerdem ermöglicht XmlArrayItemAttribute die Serialisierung abgeleiteter Klassen. Zum Beispiel kann eine weitere Klasse mit der Bezeichnung Manager, die von Employee abgeleitet wird, dem vorigen Beispiel hinzugefügt werden. Wenn Sie XmlArrayItemAttribute nicht anwenden, schlägt der Code zur Laufzeit fehl, weil der abgeleitete Klassentyp nicht erkannt wird. Um dieses Problem zu beheben, wenden Sie das Attribut zweimal an, und legen Sie jedes Mal die Type-Eigenschaft für jeden zulässigen Typ (Basisklasse und abgeleitete Klasse) fest.

Public Class Group
    <XmlArrayItem(Type:=GetType(Employee)), _
    XmlArrayItem(Type:=GetType(Manager))> _
    Public Employees() As Employee
End Class
Public Class Employee
    Public Name As String
End Class
Public Class Manager
Inherits Employee
    Public Level As Integer
End Class
public class Group {
    [XmlArrayItem(Type = typeof(Employee)),
    XmlArrayItem(Type = typeof(Manager))]
    public Employee[] Employees;
}
public class Employee {
    public string Name;
}
public class Manager:Employee {
    public int Level;
}

Eine serialisierte Instanz könnte etwa wie folgt aussehen.

<Group>
<Employees>
    <Employee>
        <Name>Haley</Name>
    </Employee>
    <Employee xsi:type = "Manager">
        <Name>Ann</Name>
        <Level>3</Level>
    </Employee>
</Employees>
</Group>

Serialisieren eines Arrays als Abfolge von Elementen

Sie können ein Array auch als eine flache Abfolge von XML-Elementen serialisieren, indem Sie XmlElementAttribute auf das Feld anwenden, sodass das Array wie folgt zurückgegeben wird.

Public Class Group
    <XmlElement> _
    Public Employees() As Employee
End Class
public class Group {
    [XmlElement]
    public Employee[] Employees;
}

Eine serialisierte Instanz könnte etwa wie folgt aussehen.

<Group>
<Employees>
    <Name>Haley</Name>
</Employees>
<Employees>
    <Name>Noriko</Name>
</Employees>
<Employees>
    <Name>Marco</Name>
</Employees>
</Group>

Eine weitere Möglichkeit, die beiden XML-Streams zu unterscheiden, besteht in der Verwendung des Tools für die XML-Schemadefinition zur Generierung der XML-Schemadokumentdateien (XSD) aus dem kompilierten Code. (Nähere Informationen zur Verwendung dieses Tools finden Sie unter Das XML Schema Definition-Tool und die XML-Serialisierung.) Wenn keine Attribute auf das Feld angewendet werden, wird das Element auf die folgende Weise durch das Schema beschrieben.

<xs:element minOccurs="0" maxOccurs ="1" name="Employees" type="ArrayOfEmployee" />

Wird XmlElementAttribute auf das Feld angewendet, wird das Element durch das resultierende Schema auf folgende Weise beschrieben.

<xs:element minOccurs="0" maxOccurs="unbounded" name="Employees" type="Employee" />

Serialisieren einer ArrayList-Klasse

Die ArrayList-Klasse kann eine Auflistung verschiedenartiger Objekte enthalten. Daher können Sie eine ArrayList-Klasse wie ein Array verwenden. Statt ein Feld zu erstellen, das ein Array von Objekten mit Typbindung zurückgibt, können Sie auch ein Feld erstellen, das ein einzelnes ArrayList-Objekt zurückgibt. Ebenso wie mit Arrays müssen Sie die XmlSerializer-Klasse jedoch über die Typen der in der ArrayList-Klasse enthaltenen Objekte informieren. Hierzu müssen Sie dem Feld mehrere Instanzen von XmlElementAttribute zuweisen, wie im folgenden Beispiel gezeigt wird.

Public Class Group
    <XmlElement(Type:=GetType(Employee)), _
    XmlElement(Type:=GetType(Manager))> _
    Public Info As ArrayList
End Class
public class Group {
    [XmlElement(Type = typeof(Employee)),
    XmlElement(Type = typeof(Manager))]
    public ArrayList Info;
}

Kontrollieren von Serialisierung von Klassen mit den Attributen XmlRootAttribute und XmlTypeAttribute

Es gibt zwei Attribute, die (ausschließlich) auf Klassen angewendet werden können: XmlRootAttribute und XmlTypeAttribute. Diese Attribute sind sich sehr ähnlich. XmlRootAttribute kann nur auf eine einzige Klasse angewendet werden: auf die Klasse, die bei Serialisierung das öffnende und schließende Element, d. h. das Stammelement, darstellt. XmlTypeAttribute kann dagegen auf beliebige Klassen einschließlich der Stammklasse angewendet werden.

So ist beispielsweise im vorigen Beispiel die Group-Klasse die Stammklasse, und alle ihre öffentlichen Felder und Eigenschaften werden zu XML-Elementen, die im XML-Dokument enthalten sind. Es kann daher nur eine Stammklasse geben. Durch die Anwendung von XmlRootAttribute können Sie den von XmlSerializer generierten XML-Stream steuern. Beispielsweise können Sie den Elementnamen und den Namespace ändern.

XmlTypeAttribute ermöglicht es Ihnen, das Schema des generierten XML-Streams zu steuern. Diese Fähigkeit ist hilfreich, wenn Sie das Schema über einen XML-Webdienst veröffentlichen müssen. Im folgenden Beispiel werden das XmlTypeAttribute-Attribut und das XmlRootAttribute-Attribut auf dieselbe Klasse angewendet.

<XmlRoot("NewGroupName"), _
XmlType("NewTypeName")> _
Public Class Group
    Public Employees() As Employee
End Class
[XmlRoot("NewGroupName")]
[XmlType("NewTypeName")]
public class Group {
    public Employee[] Employees;
}

Wenn diese Klasse kompiliert wird und ihr Schema mit dem XML Schema Definition-Tool generiert wurde, erhalten Sie als Beschreibung von Group den folgenden XML-Stream.

<xs:element name="NewGroupName" type="NewTypeName" />

Wenn Sie dagegen eine Instanz der Klasse serialisieren würden, würde das XML-Dokument lediglich NewGroupName enthalten.

<NewGroupName>
    . . .
</NewGroupName>

Verhindern der Serialisierung mit dem Attribut XmlIgnoreAttribute

Es kann vorkommen, dass eine öffentliche Eigenschaft oder ein öffentliches Feld nicht serialisiert werden muss. Zum Beispiel konnte ein Feld oder eine Eigenschaft zum Speichern von Metadaten verwendet werden. Wenden Sie in diesen Fällen XmlIgnoreAttribute auf das Feld oder die Eigenschaft an. XmlSerializer überspringt dann das Feld bzw. die Eigenschaft.

Siehe auch