Manipulação de XML e JSON em C# com Exemplos Práticos

Em aplicações .NET, lidar com dados estruturados como XML e JSON é uma tarefa comum. O C# oferece várias abordagens para analisar, modificar e seriailzar esses formatos de maneira eficiente.

Análise de XML em C#

O framework .NET fornece múltiplas APIs para manipulação de XML. Abaixo estão as principais formas de uso:

Utilizando XmlDocument

var doc = new XmlDocument();
doc.Load("dados.xml");

var novoElemento = doc.CreateElement("imagem");
novoElemento.SetAttribute("caminho", "foto6.png");

var alvo = doc.SelectSingleNode("conteudo/secao/pagina/galeria/pasta");
alvo?.AppendChild(novoElemento);

doc.Save("dados.xml");

Usando LINQ to XML (XDocument)

var raiz = XElement.Load("dados.xml");
foreach (var atributo in raiz.Attributes())
{
    raiz.Add(new XElement(atributo.Name, atributo.Value));
}
Console.WriteLine(raiz);

Exemplo completo: Conversão de XML para lista de objetos

Considere o seguinte arquivo XML representando custos de veículos:

<?xml version="1.0" encoding="utf-8"?>
<Veiculos>
  <Custo>
    <ID>20130821133126</ID>
    <TempoAtivo>60</TempoAtivo>
    <TempoInativo>30</TempoInativo>
    <Valor>0.4</Valor>
  </Custo>
  <Custo>
    <ID>20130821014316</ID>
    <TempoAtivo>120</TempoAtivo>
    <TempoInativo>60</TempoInativo>
    <Valor>0.3</Valor>
  </Custo>
</Veiculos>

Classe de modelo:

public class RegistroCusto
{
    public RegistroCusto(string id, string ativo, string inativo, float valor)
    {
        Identificador = id;
        TempoAtivo = ativo;
        TempoInativo = inativo;
        ValorHora = valor;
    }

    public string Identificador { get; set; }
    public string TempoAtivo { get; set; }
    public string TempoInativo { get; set; }
    public float ValorHora { get; set; }
}

Processamento:

var registros = new List<RegistroCusto>();
var documento = new XmlDocument();
documento.Load("dados.xml");

var nos = documento.SelectSingleNode("Veiculos")?.ChildNodes;
if (nos != null)
{
    foreach (XmlNode no in nos)
    {
        var registro = new RegistroCusto(
            no.SelectSingleNode("ID")?.InnerText ?? "",
            no.SelectSingleNode("TempoAtivo")?.InnerText ?? "",
            no.SelectSingleNode("TempoInativo")?.InnerText ?? "",
            float.Parse(no.SelectSingleNode("Valor")?.InnerText ?? "0")
        );
        registros.Add(registro);
    }
}

foreach (var item in registros)
{
    Console.WriteLine($"{item.Identificador} | {item.TempoAtivo} | {item.TempoInativo} | {item.ValorHora}");
}

Trabalhando com JSON em C#

A biblioteca Newtonsoft.Json (Json.NET) é a mais popular para manipulação de JSON em C#. Ela permite desserialização direta para objetos tipados ou navegação dinâmica via JObject.

Exemplo básico de desserialização

Dado um JSON de operações de usuário:

[
  {
    "ProxyUserID": "5d9ad5dc1c5e494db1d1b4d8d79b60a7",
    "UserName": "João Silva",
    "OperationName": "Aprovação de contrato",
    "SignDate": "2013-06-19T10:31:26"
  },
  {
    "ProxyUserID": "2c96c3943826ea93013826eafe6d0089",
    "UserName": "Maria Souza",
    "OperationName": "Revisão de contrato",
    "SignDate": "2013-06-20T09:37:11"
  }
]

Defina a classe correspondente:

public class RegistroOperacao
{
    public string ProxyUserID { get; set; }
    public string UserName { get; set; }
    public string OperationName { get; set; }
    public DateTime SignDate { get; set; }
}

E realize a conversão:

string json = /* conteúdo acima */;
var operacoes = JsonConvert.DeserializeObject<List<RegistroOperacao>>(json);

foreach (var op in operacoes)
{
    Console.WriteLine($"Usuário: {op.UserName} - Data: {op.SignDate:yyyy-MM-dd HH:mm}");
}

JSON aninhado

Para estruturas complexas, crie classes aninhadas. Exemplo:

public class RegistroDetalhado
{
    public bool Fantasma { get; set; }
    public string Identificador { get; set; }
    public DadosInternos Conteudo { get; set; }
}

public class DadosInternos
{
    public int MID { get; set; }
    public string Nome { get; set; }
    public string Descricao { get; set; }
    public string Status { get; set; }
}

Uso:

string jsonAninhado = "[{'Fantasma':true,'Identificador':'20130717001','Conteudo':{'MID':1019,'Nome':'Produto X'}}]";
var lista = JsonConvert.DeserializeObject<List<RegistroDetalhado>>(jsonAninhado);

foreach (var item in lista)
{
    Console.WriteLine($"ID interno: {item.Conteudo.MID} - Nome: {item.Conteudo.Nome}");
}

Navegação dinâmica com JObject

Quando não se deseja criar classes, é possível acessar propriedades diretamente:

string jsonDinamico = @"{""status"":true,""info"":{""nome"":""Produto A"",""estoque"":{""local"":""A-01"",""quantidade"":50}}}";

var obj = JObject.Parse(jsonDinamico);
Console.WriteLine(obj["info"]["estoque"]["local"]); // Saída: A-01
Console.WriteLine(obj["info"]["nome"]);           // Saída: Produto A

Serialização de estruturas recursivas

Para árvores ou hierarquias, defina classes auto-referentes:

public class NodeCategoria
{
    public int Id { get; set; }
    public string Valor { get; set; }
    public List<NodeCategoria> Filhos { get; set; } = new List<NodeCategoria>();
}

// Uso:
var raiz = new NodeCategoria
{
    Id = 1,
    Valor = "Eletrônicos",
    Filhos =
    {
        new NodeCategoria
        {
            Id = 2,
            Valor = "Celulares",
            Filhos =
            {
                new NodeCategoria { Id = 3, Valor = "Android" },
                new NodeCategoria { Id = 4, Valor = "iOS" }
            }
        }
    }
};

string jsonGerado = JsonConvert.SerializeObject(raiz, Formatting.Indented);
Console.WriteLine(jsonGerado);

Leitura de tokens brutos

Para análise manual ou validação:

string jsonBruto = @"{""Total"":1543,""Itens"":[{""Unidade"":6119,""Nome"":""C""}]}";
using var leitor = new JsonTextReader(new StringReader(jsonBruto));

while (leitor.Read())
{
    Console.WriteLine($"{leitor.TokenType,-15} | {leitor.ValueType?.Name,-10} | {leitor.Value}");
}

Tags: C# XML JSON Newtonsoft.Json LINQ-to-XML

Publicado em 9-29 02:44