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

0 respostas

Deixe uma resposta

Want to join the discussion?
Feel free to contribute!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *