Come faccio a leggere e analizzare un file XML in C #?


362

Come faccio a leggere e analizzare un file XML in C #?


2
La soluzione più semplice è usare LINQ to XML. Vedi il mio esempio
Konstantin Tarkus,

Risposte:


480

XmlDocument per leggere un XML dalla stringa o dal file.

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

o

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

quindi trova un nodo sotto di esso, cioè in questo modo

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
}

quindi leggi il testo all'interno di quel nodo in questo modo

string text = node.InnerText;

o leggi un attributo

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

Controlla sempre null su Attributes ["qualcosa"] poiché sarà null se l'attributo non esiste.


1
Valido, ma Linq to XML è molto più bello.
Finglas,

3
Anche se dici che è "più bello", ci sono altri svantaggi nel farlo in questo modo rispetto a LINQ? Personalmente ho trovato questo metodo per essere il più semplice, almeno per le mie esigenze.
Kolors,

6
L'ho scritto prima di iniziare a utilizzare LINQ. LINQ è carino e può avere una leggibilità più semplice. Oggi uso principalmente LINQ. Ma alcuni componenti necessitano degli oggetti XML di vecchio stile, quindi viene ancora utilizzato di tanto in tanto. Consiglierei di provare sia il "vecchio stile" qui che LINQ e vedere cosa ti sta bene.
Wolf5,

1
La XmlNode node = XmlDocument.Docu...linea non dovrebbe essere davvero XmlNode = doc.Docu...? Perché la risposta è stata modificata e doc.rimossa?
wasatchwizard,

Vero. Non ho idea del perché l'ho cambiato ... Risolverà.
Wolf5,

219

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

Riferimento : LINQ to XML su MSDN


16
XDocument.Parse ( "<xml> qualcosa </ xml>"); per una stringa.
Wolf5,

2
Le persone che non includono le inclusioni sono cattive, grazie per la risposta però :)
Gabriel Garcia,

@GabrielGarcia vero, a volte il principiante si blocca per errore di inclusione mancante
Anonimo

1
quali sono le parti rilevanti?
sayth

18

Ecco un'applicazione che ho scritto per leggere sitemap 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()
        {
        }
    }
}

Codice sul cestino della pasta http://pastebin.com/yK7cSNeY


12

Ci sono molti modi, alcuni:

  • XmlSerializer. usa una classe con lo schema di destinazione che vuoi leggere - usa XmlSerializer per caricare i dati in un Xml in un'istanza della classe.
  • Linq 2 xml
  • XmlTextReader.
  • XmlDocument
  • XPathDocument (accesso di sola lettura)

2
In realtà, XmlReader.Create invece di usare direttamente XmlTextReader, dal .NET 2.0.
John Saunders,


7

Linq a XML.

Inoltre, VB.NET ha un supporto di analisi XML molto migliore tramite il compilatore rispetto a C #. Se hai l'opzione e il desiderio, dai un'occhiata.


"Tutto sbagliato"? Non accurato, dovrei pensare, a meno che questa affermazione non fosse per scherzo. L'OP non ha fornito informazioni. sulla versione .NET su cui lavora.
Cerebrus,

1
Eh si Era per scherzo, ma non sono divertente, quindi l'ho rimosso.

7

È possibile utilizzare un DataSet per leggere stringhe XML.

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

Pubblicare questo per motivi di informazione.


molto bene! è il modo più veloce che ho trovato per condividere informazioni da colonne XML sql e .net !!
elle0087,

Non è l'ideale quando si hanno più livelli in quanto sembra mettere ciascun livello nella propria tabella all'interno del set di dati.
Lenny K

Va ancora bene anche per quello. Immagino che dipenda davvero dall'aspetto dei tuoi dati e da quanti strati profondi siano i tuoi dati.
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;
            }
        }
    }

È possibile evitare la prima istruzione e specificare semplicemente il nome del percorso nel costruttore di XmlTextReader.


0

Esistono diversi modi, a seconda di dove vuoi arrivare. XmlDocument è più leggero di XDocument, ma se si desidera verificare in modo minimalista che una stringa contenga XML, l'espressione regolare è probabilmente la scelta più rapida e leggera che si possa fare. Ad esempio, ho implementato Smoke Tests con SpecFlow per la mia API e desidero testare se uno dei risultati in qualsiasi XML valido, quindi utilizzerei un'espressione regolare. Ma se ho bisogno di estrarre valori da questo XML, lo analizzerei con XDocument per farlo più velocemente e con meno codice. Oppure userei XmlDocument se dovessi lavorare con un grande XML (e qualche volta lavoro con XML che sono circa 1M di linee, anche di più); allora potrei persino leggerlo riga per riga. Perché? Prova ad aprire più di 800 MB in byte privati ​​in Visual Studio; anche in produzione non dovresti avere oggetti più grandi di 2 GB. Puoi farlo con un twerk, ma non dovresti. Se dovessi analizzare un documento, che contiene MOLTE righe, probabilmente questi documenti sarebbero CSV.

Ho scritto questo commento, perché vedo molti esempi con XDocument. XDocument non è adatto a documenti di grandi dimensioni o quando si desidera verificare solo se il contenuto è XML valido. Se si desidera verificare se l'XML stesso ha senso, è necessario Schema.

Ho anche votato verso il basso la risposta suggerita, perché credo che abbia bisogno delle informazioni di cui sopra al suo interno. Immagina di dover verificare se 200 M di XML, 10 volte all'ora, sono XML validi. XDocument sprecherà molte risorse.

prasanna venkatesh afferma anche che potresti provare a riempire la stringa in un set di dati, indicherà anche un XML valido.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.