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 obter mais informações sobre como criar um fluxo XML alternativo, consulte Como especificar um nome de elemento alternativo para um fluxo XML.
Nota
Se o XML gerado deve estar em conformidade com a seção 5 do documento W3C (World Wide Web Consortium) intitulado Simple Object Access Protocol (SOAP) 1.1, use os atributos listados em Atributos que controlam a serialização SOAP codificada.
Por padrão, um nome de elemento XML é determinado pelo nome da classe ou membro. Em uma classe chamada Book
, um campo chamado ISBN produzirá uma marca <ISBN>
de elemento XML , conforme mostrado no exemplo a seguir:
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 você quiser dar ao elemento um novo nome. O código a seguir mostra como um atributo habilita essa funcionalidade definindo 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 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 matrizes
Os XmlArrayAttribute atributos e controlam XmlArrayItemAttribute 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 intitulado Esquema XML Parte 2: 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 de inclusão que resulta quando uma matriz é serializada. Por exemplo, por padrão, a serialização da matriz abaixo resultará em um elemento XML chamado Employees
. O Employees
elemento conterá uma série de elementos nomeados após o tipo Employee
de matriz .
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>
Ao aplicar 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.
Nota
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 nomeada Manager
que deriva de pode ser adicionada Employee
ao exemplo anterior. Se você não aplicar o XmlArrayItemAttribute, o código falhará em tempo de execução porque o tipo de classe derivado não será reconhecido. Para corrigir esse resultado, aplique o atributo duas vezes, cada vez definindo a Type propriedade 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 simples de elementos XML aplicando a 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 de diferenciar os dois fluxos XML é usar a ferramenta de definição de esquema XML para gerar os arquivos de documento do esquema XML (XSD) a partir do código compilado. Para obter mais informações sobre como usar a ferramenta, consulte A ferramenta de definição de esquema XML e 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 uma ArrayList
A ArrayList classe pode conter uma coleção de objetos diversos. Portanto, você pode usar um ArrayList tanto quanto você usa uma matriz. Em vez de criar um campo que retorna uma matriz de objetos digitados, no entanto, você pode criar um campo que retorna um único ArrayList. No entanto, como acontece com matrizes, você deve informar o XmlSerializer dos tipos de objetos que contém ArrayList . 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 a apenas 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 Group
classe é a classe raiz e todos os seus campos públicos e propriedades tornam-se os elementos XML encontrados no documento XML. Portanto, você pode ter apenas uma classe raiz. Ao aplicar o XmlRootAttribute, você pode controlar o fluxo XML gerado pelo XmlSerializer. Por exemplo, você pode alterar o nome do elemento e o namespace.
O XmlTypeAttribute permite controlar o esquema do XML gerado. Esse recurso é útil quando você precisa publicar o esquema por meio de um XML Web Service. O exemplo a seguir 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 compilada e a ferramenta de definição de esquema XML for usada para gerar seu esquema, você encontrará o seguinte XML descrevendo Group
:
<xs:element name="NewGroupName" type="NewTypeName" />
Por outro lado, se você serializasse uma instância da classe, somente NewGroupName
seria encontrado no documento XML:
<NewGroupName>
. . .
</NewGroupName>
Impedindo a serialização com o XmlIgnoreAttribute
Você pode se deparar com uma situação em que uma propriedade pública ou campo não precisa ser serializado. Por exemplo, um campo ou propriedade pode ser usado para conter metadados. Nesses casos, aplique o XmlIgnoreAttribute ao campo ou propriedade e o XmlSerializer irá pulá-lo.