Controlar a serialização XML usando atributos

Os atributos podem ser usados para controlar a serialização XML de um objeto ou criar um fluxo XML alternativo do mesmo conjunto de classes. Para obter mais informações sobre como criar um fluxo XML alternativo, consulte Como especificar um nome de elemento alternativo para um fluxo XML.

Observação

Se o XML gerado precisar estar em conformidade com a seção 5 do documento intitulado Simple Object Access Protocol (SOAP) 1.1 (Protocolo SOAP 1.1) do W3C (World Wide Web Consortium), use os atributos listados em Atributos que controlam a serialização SOAP codificada.

Por padrão, um nome de elemento XML é determinado pela classe ou nome do membro. Em uma classe chamada Book, um campo chamado ISBN produzirá uma marcação de elemento XML <ISBN>, conforme mostrado seguinte exemplo:

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>.

Esse comportamento padrão poderá ser modificado se você quiser dar ao elemento um novo nome. O seguinte código mostra como um atributo habilita essa funcionalidade definindo a propriedade ElementName de um XmlElementAttribute:

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

Para obter mais informações sobre atributos, consulte Atributos. Para obter uma lista de atributos que controlam a serialização XML, consulte Atributos que controlam a serialização XML.

Controlando a serialização de matriz

Os atributos XmlArrayAttribute e XmlArrayItemAttribute para controlam a serialização de matrizes. Usando esses atributos, você pode controlar o nome do elemento, o namespace e o tipo de dados XSD (esquema XML) conforme definido no documento do W3C Parte 2 do esquema XML: tipos de dados. Você também pode especificar os tipos que podem ser incluídos em uma matriz.

O XmlArrayAttribute determinará as propriedades do elemento XML incluído que resulta quando uma matriz é serializada. Por exemplo, por padrão, serializar a matriz abaixo resultará em um elemento XML denominado Employees. O elemento Employees conterá uma série de elementos nomeados de acordo com o tipo de matriz Employee.

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;
}

Uma instância serializada pode ser semelhante ao seguinte código:

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

Aplicando um XmlArrayAttribute, você pode alterar o nome do elemento XML, da seguinte maneira:

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

O XML resultante pode ser semelhante ao seguinte código:

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

O XmlArrayItemAttribute, por outro lado, controla como os itens contidos na matriz são serializados.

Observação

O atributo é aplicado ao campo que retorna a matriz.

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

O XML resultante pode ser semelhante ao seguinte código:

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

Serializando classes derivadas

Outro uso do XmlArrayItemAttribute é permitir a serialização de classes derivadas. Por exemplo, outra classe denominada Manager que é derivada de Employee pode ser adicionada ao exemplo anterior. Se você não aplicar o XmlArrayItemAttribute, o código falhará em tempo de execução porque o tipo da classe derivada não será reconhecido. Para corrigir esse resultado, aplique o atributo duas vezes, cada vez que definir a propriedade Type para cada tipo aceitável (base e derivada).

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;
}

Uma instância serializada pode ser semelhante ao seguinte código:

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

Serializando uma matriz como uma sequência de elementos

Você também pode serializar uma matriz como uma sequência plana dos elementos XML aplicando um XmlElementAttribute ao campo que retorna a matriz da seguinte maneira:

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

Uma instância serializada pode ser semelhante ao seguinte código:

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

Outra maneira para diferenciar os dois fluxos XML é usar a Ferramenta de Definição de Esquema XML para gerar os arquivos de documento de esquema XSD de código compilado. Para obter mais informações sobre como usar a ferramenta, consulte A ferramenta de definição de esquema XML e a serialização XML. Quando nenhum atributo é aplicado ao campo, o esquema descreve o elemento da seguinte maneira:

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

Quando o XmlElementAttribute é aplicado ao campo, o esquema resultante descreve o elemento da seguinte maneira:

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

Serializando um ArrayList

A classe ArrayList pode conter uma coleção de vários objetos. Você pode, portanto, usar um ArrayList da mesma maneira que usa uma matriz. Em vez de criar um campo que retorna uma matriz de objetos tipados, no entanto, você pode criar um campo que retorna um único ArrayList. No entanto, da mesma forma que ocorre com matrizes, você deverá informar o XmlSerializer dos tipos de objetos que o ArrayList contém. Para fazer isso, atribua várias instâncias do XmlElementAttribute ao campo, conforme mostrado no exemplo a seguir.

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;
}

Controlando a serialização de classes usando XmlRootAttribute e XmlTypeAttribute

Você pode aplicar dois atributos somente a uma classe: XmlRootAttribute e XmlTypeAttribute. Esses atributos são semelhantes. O XmlRootAttribute pode ser aplicado somente a uma classe: a classe que, quando serializada, representa o elemento de abertura e fechamento do documento XML. Em outras palavras, o elemento raiz. O XmlTypeAttribute, por outro lado, pode ser aplicado a qualquer classe, incluindo a classe raiz.

Por exemplo, nos exemplos anteriores, a classe Group é a classe raiz, e todos os seus campos públicos e propriedades tornam-se elementos XML encontrados no documento XML. Portanto, você pode ter apenas uma classe raiz. Aplicando o XmlRootAttribute, você pode controlar o fluxo XML produzido pelo XmlSerializer. Por exemplo, você pode alterar o nome e o namespace do elemento.

O XmlTypeAttribute permite que você controle o esquema do XML gerado. Esse recurso é útil quando você precisa publicar o esquema por um serviço Web XML. O seguinte exemplo aplica o XmlTypeAttribute e o XmlRootAttribute à mesma classe:

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

Se essa classe for criada, e a ferramenta de Definição de Esquema XML for usada para gerar seu esquema, você descobriria o seguinte XML descrevendo o Group:

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

Por outro lado, se você quisesse serializar uma instância da classe, somente NewGroupName seria encontrado no documento XML:

<NewGroupName>
    . . .
</NewGroupName>

Evitando a serialização com o XmlIgnoreAttribute

Você pode se deparar com uma situação em que uma propriedade ou campo público não precisa ser serializado. Por exemplo, um campo ou propriedade podem ser usados para conter metadados. Nesses casos, aplicar o XmlIgnoreAttribute ao campo ou propriedade e o XmlSerializer o ignorarão.

Confira também