Partilhar via


Controlar a serialização XML usando atributos

Os atributos podem ser usados para controlar a serialização XML de um objeto ou para criar um fluxo XML alternativo a partir do mesmo conjunto de classes. Para mais informações sobre como criar um fluxo XML alternativo, veja Como: Especificar um Nome de Elemento Alternativo para um Fluxo XML.

Observação

Se o XML gerado tiver de cumprir a secção 5 do documento do World Wide Web Consortium (W3C) intitulado Simple Object Access Protocol (SOAP) 1.1, utilize os atributos listados em Attributes That Control Coded SOAP Serialization.

Por defeito, o nome de um elemento XML é determinado pelo nome da classe ou membro. Numa classe chamada Book, um campo chamado ISBN produzirá uma etiqueta <ISBN>de elemento XML , como mostrado no 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>.

O comportamento padrão pode ser alterado se quiseres dar um novo nome ao elemento. O código seguinte mostra como um atributo permite esta funcionalidade ao definir a ElementName propriedade 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 mais informações sobre atributos, consulte Atributos. Para uma lista de atributos que controlam a serialização XML, veja Atributos que Controlam a Serialização XML.

Controlo da serialização de arrays

Os XmlArrayAttribute atributos e XmlArrayItemAttribute controlam a serialização dos arrays. Usando estes atributos, pode controlar o nome do elemento, o espaço de nomes e o tipo de dados XML Schema (XSD) conforme definido no documento do W3C intitulado XML Schema Parte 2: Tipos de dados. Também pode especificar os tipos que podem ser incluídos num array.

XmlArrayAttribute determinará as propriedades do elemento XML que envolve o array quando o array é serializado. Por exemplo, como padrão, serializar o array abaixo resultará num elemento XML chamado Employees. O elemento Employees conterá uma série de elementos com o nome do tipo de array 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 assemelhar-se ao seguinte código:

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

Ao aplicar um XmlArrayAttribute, pode alterar o nome do elemento XML, da seguinte forma:

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

O XML resultante pode assemelhar-se ao seguinte código:

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

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

Observação

O atributo é aplicado ao campo que devolve o array.

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

O XML resultante pode assemelhar-se ao seguinte código:

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

Serialização de Classes Derivadas

Outro uso do XmlArrayItemAttribute é permitir a serialização de classes derivadas. Por exemplo, outra classe nomeada Manager que deriva de Employee pode ser adicionada ao exemplo anterior. Se não aplicares o XmlArrayItemAttribute, o código falhará em tempo de execução porque o tipo de classe derivado não será reconhecido. Para remediar este resultado, aplique o atributo duas vezes, cada vez definindo a Type propriedade para cada tipo aceitável (base e derivado).

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 assemelhar-se ao seguinte código:

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

Serializar um array como uma sequência de elementos

Também pode serializar um array como uma sequência plana de elementos XML aplicando a XmlElementAttribute ao campo que retorna o array da seguinte forma:

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

Uma instância serializada pode assemelhar-se ao seguinte código:

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

Outra forma de diferenciar os dois fluxos XML é usar a ferramenta XML Schema Definition para gerar os ficheiros de documento XML Schema (XSD) a partir do código compilado. Para mais informações sobre a utilização da ferramenta, consulte A Ferramenta de Definição de Esquemas XML e Serialização XML. Quando nenhum atributo é aplicado ao campo, o esquema descreve o elemento da seguinte forma:

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

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

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

Serializar uma ArrayList

A ArrayList classe pode conter uma coleção de objetos diversos. Por isso, pode usar um ArrayList tal como usar um array. No entanto, em vez de criar um campo que devolve um array de objetos tipados, pode-se criar um campo que devolve um único ArrayList. No entanto, tal como nos arrays, deve informar o XmlSerializer sobre os tipos de objetos que o ArrayList contém. Para alcançar isto, atribui-se múltiplas instâncias do XmlElementAttribute ao campo, como mostrado no exemplo seguinte.

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

Controlo da serialização de classes usando XmlRootAttribute e XmlTypeAttribute

Pode aplicar apenas dois atributos a uma classe: XmlRootAttribute e XmlTypeAttribute. Estes atributos são semelhantes. O XmlRootAttribute pode ser aplicado apenas a uma classe: a classe que, quando serializada, representa o elemento de abertura e fecho do documento XML — ou seja, o elemento raiz. O XmlTypeAttribute, por outro lado, pode ser aplicado a qualquer classe, incluindo a classe raiz.

Por exemplo, nos exemplos anteriores, a Group classe é a classe raiz, e todos os seus campos públicos e propriedades tornam-se os elementos XML encontrados no documento XML. Portanto, só podes ter uma classe de raiz. Ao aplicar o XmlRootAttribute, pode controlar o fluxo XML gerado pelo XmlSerializer. Por exemplo, pode alterar o nome do elemento e o namespace.

O XmlTypeAttribute permite-lhe controlar o esquema do XML gerado. Esta funcionalidade é útil quando precisa de publicar o esquema através de um serviço Web XML. O exemplo seguinte aplica tanto o XmlTypeAttribute como 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 esta classe for compilada e a ferramenta XML Schema Definition for usada para gerar o seu esquema, encontrará o seguinte XML a descrever Group:

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

Por outro lado, se serializar uma instância da classe, apenas NewGroupName estaria no documento XML.

<NewGroupName>
    . . .
</NewGroupName>

Prevenir a serialização com o XmlIgnoreAttribute

Pode deparar-se com uma situação em que uma propriedade ou campo público não precise de ser serializado. Por exemplo, um campo ou propriedade pode ser usado para conter metadados. Nesses casos, aplica o XmlIgnoreAttribute ao campo ou propriedade e o XmlSerializer saltará sobre ele.

Consulte também