¿Cómo leo y analizo un archivo XML en C #?

362

¿Cómo leo y analizo un archivo XML en C #?

Gajendra
fuente
2
La solución más simple es usar LINQ to XML. Mira mi ejemplo.
Konstantin Tarkus

Respuestas:

480

XmlDocument para leer un XML desde una cadena o desde un archivo.

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

o

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

luego encuentre un nodo debajo, es decir, así

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

o

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

luego lea el texto dentro de ese nodo como este

string text = node.InnerText;

o leer un atributo

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

Siempre verifique si hay nulo en los Atributos ["algo"] ya que será nulo si el atributo no existe.

Lobo5
fuente
1
Válido, pero Linq to XML es mucho mejor.
Finglas
3
Aunque diga que es "más agradable", ¿hay alguna otra desventaja de hacerlo de esta manera a través de LINQ? Personalmente, encontré que este método es el más simple, al menos para mis necesidades.
Kolors
66
Escribí esto antes de comenzar a usar LINQ. LINQ es agradable y puede ser más fácil de leer. Principalmente uso LINQ en estos días. Pero algunos componentes necesitan los objetos XML de estilo antiguo, por lo que todavía se usa de vez en cuando. Recomiendo probar tanto el "estilo antiguo" aquí como LINQ y ver qué le queda.
Wolf5
1
¿No debería XmlNode node = XmlDocument.Docu...ser realmente la línea XmlNode = doc.Docu...? ¿Por qué se cambió la respuesta y se doc.eliminó?
wasatchwizard
Cierto. No tengo idea de por qué cambié eso ... Se solucionará.
Wolf5
219

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

Referencia : LINQ to XML en MSDN

Konstantin Tarkus
fuente
16
XDocument.Parse ("<xml> algo </xml>"); para una cuerda
Wolf5
2
Las personas que no incluyen las inclusiones son malas, gracias por la respuesta aunque :)
Gabriel Garcia
@GabrielGarcia es cierto, a veces los principiantes se atascan en el error de incluir faltante
Anónimo
1
¿Cuáles son los relevantes incluye?
dice
18

Aquí hay una aplicación que escribí para leer mapas del sitio 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 en la papelera http://pastebin.com/yK7cSNeY

ajzeffer
fuente
12

Hay muchas maneras, algunas:

  • XmlSerializer. use una clase con el esquema de destino que desea leer: use XmlSerializer para obtener los datos en un Xml cargado en una instancia de la clase.
  • Linq 2 xml
  • XmlTextReader.
  • XmlDocument
  • XPathDocument (acceso de solo lectura)
eglasius
fuente
2
En realidad, XmlReader.Create en lugar de usar XmlTextReader directamente, desde .NET 2.0.
John Saunders
7

Linq a XML.

Además, VB.NET tiene mucho mejor soporte de análisis XML a través del compilador que C #. Si tienes la opción y el deseo, échale un vistazo.


fuente
"Todo mal"? No es exacto, debería pensar, a menos que esa declaración fuera una broma. El OP no ha proporcionado información. sobre la versión .NET en la que trabaja.
Cerebrus
1
Je, si. Estaba en broma, pero no soy gracioso, así que lo eliminé.
7

Puede usar un DataSet para leer cadenas XML.

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

Publicar esto por el bien de la información.

prasanna venkatesh
fuente
¡muy bien! ¡es la forma más rápida que encontré para compartir información de columnas sql xml y .net!
elle0087
No es ideal cuando tiene varios niveles, ya que parece poner cada nivel en su propia tabla dentro del conjunto de datos.
Lenny K
Todavía está bien para eso incluso. Supongo que realmente depende de cómo se vean sus datos y de cuántas capas de profundidad de datos estén buscando.
user2366842
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;
            }
        }
    }

Puede evitar la primera instrucción y simplemente especificar el nombre de ruta en el constructor de XmlTextReader.

Vishal Kotak
fuente
0

Hay diferentes formas, dependiendo de dónde quieras llegar. XmlDocument es más ligero que XDocument, pero si desea verificar de manera minimalista que una cadena contiene XML, entonces la expresión regular es posiblemente la opción más rápida y ligera que puede hacer. Por ejemplo, he implementado las pruebas de humo con SpecFlow para mi API y deseo probar si uno de los resultados está en un XML válido, entonces usaría una expresión regular. Pero si necesito extraer valores de este XML, lo analizaría con XDocument para hacerlo más rápido y con menos código. O usaría XmlDocument si tengo que trabajar con un gran XML (y a veces trabajo con XML que están alrededor de 1M líneas, incluso más); entonces incluso podría leerlo línea por línea. ¿Por qué? Intente abrir más de 800 MB en bytes privados en Visual Studio; incluso en producción no deberías tener objetos de más de 2GB. Puedes hacerlo con un twerk, pero no deberías. Si tuviera que analizar un documento, que contiene MUCHAS líneas, entonces estos documentos probablemente serían CSV.

He escrito este comentario, porque veo muchos ejemplos con XDocument. XDocument no es bueno para documentos grandes, o cuando solo desea verificar si el contenido es válido para XML. Si desea verificar si el XML en sí tiene sentido, entonces necesita un esquema.

También rechacé la respuesta sugerida, porque creo que necesita la información anterior dentro de sí misma. Imagine que necesito verificar si 200M de XML, 10 veces por hora, son XML válidos. XDocument desperdiciará una gran cantidad de recursos.

prasanna venkatesh también afirma que podría intentar llenar la cadena en un conjunto de datos, también indicará XML válido.

nkalfov
fuente