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