Como ler e analisar um arquivo XML em c #?

362

Como ler e analisar um arquivo XML em c #?

Gajendra
fonte
2
A solução mais simples é usar o LINQ to XML. Veja meu exemplo.
Konstantin Tarkus

Respostas:

480

XmlDocument para ler um XML da string ou do arquivo.

XmlDocument doc = new XmlDocument();
doc.Load("c:\\temp.xml");

ou

doc.LoadXml("<xml>something</xml>");

então encontre um nó abaixo dele, ou seja, assim

XmlNode node = doc.DocumentElement.SelectSingleNode("/book/title");

ou

foreach(XmlNode node in doc.DocumentElement.ChildNodes){
   string text = node.InnerText; //or loop through its children as well
}

então leia o texto dentro desse nó assim

string text = node.InnerText;

ou leia um atributo

string attr = node.Attributes["theattributename"]?.InnerText

Sempre verifique nulo nos Atributos ["alguma coisa"], pois será nulo se o atributo não existir.

Wolf5
fonte
11
Válido, mas o Linq to XML é muito melhor.
Finglas
3
Embora você diga que é "melhor", existe outra desvantagem em fazê-lo dessa maneira em relação ao LINQ? Pessoalmente, achei esse método o mais simples, pelo menos para minhas necessidades.
precisa saber é o seguinte
6
Eu escrevi isso antes de começar a usar o LINQ. O LINQ é bom e pode ter uma legibilidade mais fácil. Atualmente, eu mesmo uso o LINQ. Mas alguns componentes precisam dos objetos XML de estilo antigo, por isso ainda são usados ​​de vez em quando. Eu recomendaria tentar o "estilo antigo" aqui e o LINQ e ver o que mais combina com você.
precisa saber é o seguinte
11
A XmlNode node = XmlDocument.Docu...linha não deveria ser realmente XmlNode = doc.Docu...? Por que a resposta foi alterada e a doc.removida?
Wasatchwizard #
Verdade. Eu não tenho idéia do por que mudei isso ... Vai consertar.
precisa saber é o seguinte
218

Exemplo de LINQ to XML :

// Loading from a file, you can also load from a stream
var xml = XDocument.Load(@"C:\contacts.xml");


// Query the data and write out a subset of contacts
var query = from c in xml.Root.Descendants("contact")
            where (int)c.Attribute("id") < 4
            select c.Element("firstName").Value + " " +
                   c.Element("lastName").Value;


foreach (string name in query)
{
    Console.WriteLine("Contact's Full Name: {0}", name);
}

Referência : LINQ to XML no MSDN

Konstantin Tarkus
fonte
16
XDocument.Parse ("<xml> alguma coisa </xml>"); para uma string.
precisa saber é o seguinte
2
Pessoas que não incluem o inclui são médios, obrigado pela resposta tho :)
Gabriel Garcia
@GabrielGarcia é verdade, às vezes o iniciante ficava com o erro de falta de inclusão
Anônimo
11
quais são as inclusões relevantes?
sayth em
18

Aqui está um aplicativo que eu escrevi para ler sitemaps xml:

using System;
using System.Collections.Generic;
using System.Windows.Forms; 
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Data;
using System.Xml;

namespace SiteMapReader
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Please Enter the Location of the file");

            // get the location we want to get the sitemaps from 
            string dirLoc = Console.ReadLine();

            // get all the sitemaps 
            string[] sitemaps = Directory.GetFiles(dirLoc);
            StreamWriter sw = new StreamWriter(Application.StartupPath + @"\locs.txt", true);

            // loop through each file 
            foreach (string sitemap in sitemaps)
            {
                try
                {
                    // new xdoc instance 
                    XmlDocument xDoc = new XmlDocument();

                    //load up the xml from the location 
                    xDoc.Load(sitemap);

                    // cycle through each child noed 
                    foreach (XmlNode node in xDoc.DocumentElement.ChildNodes)
                    {
                        // first node is the url ... have to go to nexted loc node 
                        foreach (XmlNode locNode in node)
                        {
                            // thereare a couple child nodes here so only take data from node named loc 
                            if (locNode.Name == "loc")
                            {
                                // get the content of the loc node 
                                string loc = locNode.InnerText;

                                // write it to the console so you can see its working 
                                Console.WriteLine(loc + Environment.NewLine);

                                // write it to the file 
                                sw.Write(loc + Environment.NewLine);
                            }
                        }
                    }
                }
                catch { }
            }
            Console.WriteLine("All Done :-)"); 
            Console.ReadLine(); 
        }

        static void readSitemap()
        {
        }
    }
}

Código no Paste Bin http://pastebin.com/yK7cSNeY

ajzeffer
fonte
12

Há muitas maneiras, algumas:

  • XmlSerializer. use uma classe com o esquema de destino que você deseja ler - use XmlSerializer para obter os dados em um Xml carregados em uma instância da classe.
  • Linq 2 xml
  • XmlTextReader.
  • XmlDocument
  • XPathDocument (acesso somente leitura)
eglasius
fonte
2
Na verdade, XmlReader.Create em vez de usar XmlTextReader diretamente, desde o .NET 2.0.
John Saunders
7

Linq para XML.

Além disso, o VB.NET possui um suporte de análise xml muito melhor via compilador do que o C #. Se você tem a opção e o desejo, confira.


fonte
"Tudo errado"? Penso que não é preciso, a menos que essa afirmação seja brincadeira. O OP não forneceu informações. sobre a versão do .NET em que ele trabalha.
Cerebrus
11
Heh, sim. Foi brincadeira, mas não sou engraçado, então a removi.
7

Você pode usar um DataSet para ler cadeias XML.

var xmlString = File.ReadAllText(FILE_PATH);
var stringReader = new StringReader(xmlString);
var dsSet = new DataSet();
dsSet.ReadXml(stringReader);

Publicando isso para fins de informação.

prasanna venkatesh
fonte
muito bem! é a maneira mais rápida que encontrei para compartilhar informações de colunas xml sql e .net !!
Elle0087
Não é o ideal quando você tem vários níveis, pois parece colocar cada nível em sua própria tabela no conjunto de dados.
Lenny K
Ainda está bom para isso mesmo. Eu acho que depende realmente da aparência dos seus dados e de quantas camadas de profundidade você procura.
user2366842
2

Confira a classe XmlTextReader, por exemplo.

Frederik Gheysels
fonte
1
  public void ReadXmlFile()
    {
        string path = HttpContext.Current.Server.MapPath("~/App_Data"); // Finds the location of App_Data on server.
        XmlTextReader reader = new XmlTextReader(System.IO.Path.Combine(path, "XMLFile7.xml")); //Combines the location of App_Data and the file name
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    break;
                case XmlNodeType.Text:
                    columnNames.Add(reader.Value);
                    break;
                case XmlNodeType.EndElement:
                    break;
            }
        }
    }

Você pode evitar a primeira instrução e apenas especificar o nome do caminho no construtor de XmlTextReader.

Vishal Kotak
fonte
0

Existem maneiras diferentes, dependendo de onde você deseja obter. XmlDocument é mais leve que o XDocument, mas se você deseja verificar minimalisticamente que uma string contém XML, a expressão regular é possivelmente a escolha mais rápida e leve que você pode fazer. Por exemplo, eu implementei testes de fumaça com SpecFlow para minha API e desejo testar se um dos resultados está em algum XML válido - então eu usaria uma expressão regular. Mas se eu precisar extrair valores desse XML, eu o analisarei com o XDocument para fazê-lo mais rápido e com menos código. Ou eu usaria XmlDocument se tivesse que trabalhar com um grande XML (e às vezes trabalho com XMLs com cerca de 1 milhão de linhas, ainda mais); então eu poderia até ler linha por linha. Por quê? Tente abrir mais de 800 MB em bytes privados no Visual Studio; mesmo em produção, você não deve ter objetos maiores que 2 GB. Você pode com um twerk, mas não deveria. Se você tivesse que analisar um documento, que contém MUITAS linhas, esses documentos provavelmente seriam CSV.

Eu escrevi este comentário, porque vejo muitos exemplos com o XDocument. O XDocument não é bom para documentos grandes ou quando você deseja apenas verificar se o conteúdo é XML válido. Se você deseja verificar se o XML em si faz sentido, você precisa de Esquema.

Também reduzi a resposta sugerida, porque acredito que ela precisa das informações acima em si. Imagine que eu preciso verificar se 200M de XML, 10 vezes por hora, é XML válido. O XDocument desperdiçará muitos recursos.

prasanna venkatesh também afirma que você pode tentar preencher a string em um conjunto de dados; isso também indica XML válido.

nkalfov
fonte