Controllo della serializzazione XML mediante attributi

Gli attributi possono essere utilizzati per controllare la serializzazione XML di un oggetto o per creare un flusso XML alternativo dallo stesso insieme di classi. Per informazioni più dettagliate sulla creazione di un flusso XML alternativo, vedere Override della serializzazione XML.

Nota   Se il linguaggio XML generato deve essere conforme alla sezione 5 del documento del World Wide Web Consortium (www.w3.org) dal titolo "Simple Object Access Protocol (SOAP) 1.1," utilizzare gli attributi elencati in Attributi che controllano la serializzazione con codifica SOAP.

Per impostazione predefinita, un nome di elemento XML è determinato dal nome della classe o del membro. In una classe semplice denominata Book, un campo denominato ISBN produrrà un tag dell'elemento XML <ISBN>, come viene illustrato nell'esempio che segue.

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>.
[C#]
public class Book
{
    public string ISBN;
}
// When an instance of the Book class is serialized, it might 
// produce this XML:
// <ISBN>1234567890</ISBN>.

Se si desidera assegnare un nuovo nome all'elemento, è possibile cambiare questo comportamento predefinito. Nel codice che segue viene illustrato come ciò avviene in un attributo, impostando la proprietà ElementName di un XmlElementAttribute.

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

Per ulteriori informazioni sugli attributi, vedere Estensione dei metadati mediante attributi. Per un elenco degli attributi che controllano la serializzazione XML, vedere Attributi che controllano la serializzazione.

Per controllare la serializzazione con attributi

  1. Applicare uno degli attributi speciali alla classe o al membro di classe. Per un elenco degli attributi che controllano la serializzazione in modo specifico, vedere Attributi che controllano la serializzazione.
  2. Modificare, se necessario, il membro della classe. Modificare, ad esempio, il nome di un membro, ma impostare la proprietà ElementName su un valore appropriato, vale a dire un valore conforme allo schema XSD (XML Schema) dell'oggetto serializzato.
  3. Serializzare o deserializzare l'istanza della classe.

Il flusso XML ottenuto sarà conforme allo schema, ma la classe avrà un nome di metodo leggibile.

Controllo della serializzazione delle matrici

Gli attributi XmlArrayAttribute e XmlArrayItemAttribute sono progettati per controllare la serializzazione di matrici. Essi consentono di controllare il nome di elemento, lo spazio dei nomi e il tipo di dati dello schema XML (XSD), come viene definito nel documento del World Wide Web Consortium (www.w3.org) dal titolo "XML Schema Part 2: Datatypes" (informazioni in lingua inglese). È possibile anche specificare i tipi da includere in una matrice.

XmlArrayAttribute determinerà le proprietà dell'elemento XML che lo contiene, ottenuto quando una matrice viene serializzata. Per impostazione predefinita, ad esempio, la serializzazione della matrice che segue determinerà un elemento XML denominato "Employees". L'elemento Employees conterrà una serie di elementi denominati in base al tipo di matrice "Employee".

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

Un'istanza serializzata potrebbe essere simile a quanto segue.

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

Applicando un XmlArrayAttribute, è possibile modificare il nome dell'elemento XML, nel modo seguente:

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

Il linguaggio XML ottenuto potrebbe essere simile al seguente.

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

XmlArrayItemAttribute, d'altra parte, controlla il modo in cui gli elementi contenuti nella matrice vengono serializzati. Nell'esempio che segue l'attributo viene applicato al campo che restituisce la matrice.

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

Il linguaggio XML ottenuto potrebbe essere simile al seguente.

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

Serializzazione di classi derivate

Un altro utilizzo di XmlArrayItemAttribute consiste nel consentire la serializzazione di classi derivate. Un'altra classe denominata Manager che deriva da Employee, ad esempio, può essere aggiunta all'esempio precedente. Se non si applica XmlArrayItemAttribute, il codice non verrà eseguito correttamente in fase di esecuzione in quanto la classe derivata non sarà riconosciuto. Per risolvere il problema, applicare l'attributo due volte, impostando ogni volta la proprietà XmlArrayItemAttribute.Type per ogni tipo accettabile (di base e derivato).

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
[C#]
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;
}

Un'istanza serializzata potrebbe essere simile a quanto segue.

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

Serializzazione di una matrice come una sequenza di elementi

È possibile anche serializzare una matrice come sequenza "flat" di elementi XML applicando un XmlElementAttribute al campo che restituisce la matrice, nel modo seguente:

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

Un'istanza serializzata potrebbe essere simile a quanto segue.

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

Un altro modo per differenziare i due flussi XML consiste nell'utilizzare lo strumento di definizione di schemi XML per generare i file del documento XSD (XML Schema) dal codice compilato. Per informazioni più dettagliate sull'utilizzo dello strumento, vedere Lo strumento di definizione di schemi XML e la serializzazione XML. Quando al campo non viene applicato alcun attributo, lo schema descrive l'elemento nel seguente modo:

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

Quando al campo viene applicato l'attributo XmlElementAttribute, lo schema ottenuto descrive l'elemento nel seguente modo:

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

Serializzazione di una classe ArrayList

La classe ArrayList può contenere un insieme di diversi oggetti. È possibile pertanto utilizzare una ArrayList come si utilizzerebbe una matrice. Anziché creare un campo che restituisce una matrice di oggetti tipizzati, tuttavia, è possibile creare un campo che restituisce una singola ArrayList. La gestione delle matrici prevede comunque che XmlSerializer sia a conoscenza dei tipi di oggetti contenuti nella classe ArrayList. A tale scopo, assegnare più istanze di XmlElementAttribute al campo, come viene illustrato nell'esempio che segue.

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

Controllo della serializzazione di classi mediante XmlRootAttribute e XmlTypeAttribute

Esistono due attributi che è possibile applicare a una classe (e solo a una classe): XmlRootAttribute e XmlTypeAttribute. Essi sono molto simili tra loro. XmlRootAttribute può essere applicato a una sola classe: quella che, quando viene serializzata, rappresenta l'elemento di apertura e chiusura del documento XML, in altre parole, l'elemento "principale". XmlTypeAttribute, invece, può essere applicato a qualsiasi classe, inclusa quella principale.

Negli esempi precedenti la classe Group è la classe principale e tutte le relative proprietà e campi pubblici diventano gli elementi XML trovati nel documento XML. Può esistere pertanto una sola classe principale. Applicando l'attributo XmlRootAttribute, è possibile controllare il flusso XML generato da XmlSerializer. Il nome dell'elemento e lo spazio dei nomi, ad esempio, possono essere modificati.

XmlTypeAttribute consente di controllare lo schema del linguaggio XML generato. Questa funzionalità risulta utile quando è necessario pubblicare lo schema attraverso un servizio Web XML. L'esempio che segue applica sia XmlTypeAttribute che XmlRootAttribute alla stessa classe.

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

Se questa classe viene compilata, e lo strumento di definizione di schemi XML viene utilizzato per generarne lo schema, il linguaggio XML che descrive Group sarà il seguente:

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

Al contrario, se è necessario serializzare un'istanza della classe, nel documento XML verrà trovato solo NewGroupName.

<NewGroupName>
    . . .
</NewGroupName>

Impedimento della serializzazione con XmlIgnoreAttribute

Possono verificarsi delle situazioni in cui non è necessario serializzare un campo o una proprietà pubblica. Un campo o una proprietà possono essere utilizzati, ad esempio, per contenere metadati. In questi casi, applicare XmlIgnoreAttribute al campo o alla proprietà e XmlSerializer lo salterà.

Vedere anche

Attributi che controllano la serializzazione XML | Attributi che controllano la serializzazione con codifica SOAP | Introduzione alla serializzazione XML | Esempi di serializzazione XML | Override della serializzazione XML