Como converter XML em Objetos no C# de forma simples
Olá povo! Nesses últimos dias estava trabalhando em um projeto legado e precisei dar manutenção em uma estrutura para leitura de XML, convertê-los em objetos de domínio e utilizar os dados no projeto, porém me deparei com leituras de XML com o XmlElement e suas subclasses. Mas eles funcionam? Claro que Sim, mas existe uma maneira muito mais simples de pegar os dados de um arquivo XML e converter em um Objeto e vou te mostrar como.
Fazer a leitura do XML e utilizar as classes do System.XML funcionam e muito bem, mas existem uma verbosidade ao extrair todos os dados do XML e converter para um Objeto. Por isso, vamos utilizar o XMLSerializer do próprio .NET Full Framework que funciona no Core e lógico que no 5 e 6 e por ai vai. Olha que lindo, ele usa o pacote System.Xml.Serialize.
Nesse artigo, vou mostrar exemplo para listagem com um mestre e detalhe do tradicional pedido, pois ele consegue converter o XML em vários níveis de objetos relacionados.
Para isso, vamos utilizar o XML:
<pedido>
<numero>101010</numero>
<data>2019-05-30T16:05:00</data>
<cliente>Joao da Silva</cliente>
<itens>
<item>
<id>1</id>
<produto> Mustang GT</produto>
<quantidade>2</quantidade>
</item>
<item>
<id>2</id>
<produto>Corsa Wind</produto>
<quantidade>20</quantidade>
</item>
<item>
<id>3</id>
<produto>Macbook Pro Apple</produto>
<quantidade>1</quantidade>
</item>
<item>
<id>4</id>
<produto>Agua Mineral</produto>
<quantidade>3</quantidade>
</item>
</itens>
</pedido>
Veja que é uma estrutura simples de pedidos e seus itens.
O objeto e composto por uma classe de pedidos e uma classe de pedido itens.
[XmlRoot(ElementName = "pedido")]
public class Pedido
{
[XmlElement(ElementName = "numero")]
public int Numero { get; set; }
[XmlElement(ElementName = "data")]
public DateTime Data { get; set; }
[XmlElement(ElementName = "cliente")]
public string Cliente { get; set; }
[XmlArray("itens")]
public List<PedidoItens> Itens { get; set; }
}
[XmlType("item")]
public class PedidoItens
{
[XmlElement(ElementName = "id")]
public int ProdutoID { get; set; }
[XmlElement(ElementName = "produto")]
public string Produto { get; set; }
[XmlElement(ElementName = "quantidade")]
public int Quantidade { get; set; }
}
Note que a classe está com as tags XmlRoot, XmlType, XmlElement e XmlArray. Precisamos informa – las para que o Serializer encontre as propriedades que devem ser setadas.
| XmlRoot | Indica classe raiz do objeto. Ou seja a tag de abertura do XML <pedido> |
| XmlElement | Indica os elementos da classe após o root, como <numero> e <data> |
| XmlArray | Indica os elementos que se repetirão na lista de <itens>, mas veja que existe um elemento Itens e o elemento item. |
| XmlType | Indica o subtipo de root. Geralmente quando se tem classes relacionadas essa vai ser a Tag utilizada como <item> |
Para popular o objeto vamos utilizar um Stream com o objeto FileStream. Veja:
var fileStream = new FileStream(@"./XML/pedido_tipo_1.xml", FileMode.Open); var xmlSerializer = new XmlSerializer(typeof(Pedido)); var pedido = xmlSerializer.Deserialize(fileStream);
Veja que na primeira linha temos a leitura do XML em Stream. No caso, passamos o caminho do XML ao FileStream.
Na segunda linha instanciamos o XmlSerializer com o tipo de retorno esperado.
E por último recuperamos descerializamos o XML para o Objeto pedido.
E assim a mágica acontece de forma bem simples e prática. Não precisamos montar aquela estrutura complexa de nodes e mais nodes.
Artigo curto e espero que ajude com leituras XML.
Duvidas?? Deixem os comentários ai abaixo que respondo rápido.
Os fontes se encontram no meu GitHub e bora codar.
Links uteis.
https://docs.microsoft.com/pt-br/dotnet/api/system.xml.serialization.xmlserializer.deserialize?view=net-6.0