Comment lire et analyser un fichier XML en C #?

363

Comment lire et analyser un fichier XML en C #?

Gajendra
la source
2
La solution la plus simple consiste à utiliser LINQ to XML. Voir mon exemple.
Konstantin Tarkus

Réponses:

480

XmlDocument pour lire un XML à partir d'une chaîne ou d'un fichier.

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

ou

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

puis trouvez un nœud en dessous c'est à dire comme ça

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
}

puis lisez le texte à l'intérieur de ce nœud comme celui-ci

string text = node.InnerText;

ou lire un attribut

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

Vérifiez toujours la valeur null sur les attributs ["quelque chose"] car elle sera nulle si l'attribut n'existe pas.

Wolf5
la source
1
Valide, mais Linq to XML est beaucoup plus agréable.
Finglas
3
Bien que vous disiez que c'est «plus agréable», y a-t-il un autre inconvénient à le faire de cette façon sur LINQ? Personnellement, j'ai trouvé cette méthode la plus simple, du moins pour mes besoins.
Kolors
6
J'ai écrit ceci avant d'avoir commencé à utiliser LINQ. LINQ est agréable et peut avoir une lisibilité plus facile. J'utilise principalement LINQ moi-même ces jours-ci. Mais certains composants ont besoin des objets XML à l'ancienne, il est donc toujours utilisé de temps en temps. Je recommanderais d'essayer à la fois «l'ancien style» ici et LINQ et de voir ce qui vous convient.
Wolf5
1
La XmlNode node = XmlDocument.Docu...ligne ne devrait-elle pas vraiment l'être XmlNode = doc.Docu...? Pourquoi la réponse a-t-elle été modifiée et doc.supprimée?
wasatchwizard
Vrai. Je n'ai aucune idée de la raison pour laquelle j'ai changé cela ...
Wolf5
220

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

Référence : LINQ to XML sur MSDN

Konstantin Tarkus
la source
16
XDocument.Parse ("<xml> quelque chose </xml>"); pour une chaîne.
Wolf5
2
Les personnes qui n'incluent pas les inclusions sont méchantes, merci pour la réponse mais :)
Gabriel Garcia
@GabrielGarcia vrai, parfois le débutant s'en tient à l'erreur d'inclusion manquante
Anonyme
1
quelles sont les inclusions pertinentes?
sayth
18

Voici une application que j'ai écrite pour lire les 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()
        {
        }
    }
}

Code sur Paste Bin http://pastebin.com/yK7cSNeY

ajzeffer
la source
12

Il y a beaucoup de chemin, certains:

  • XmlSerializer. utilisez une classe avec le schéma cible que vous souhaitez lire - utilisez XmlSerializer pour obtenir les données d'un Xml chargées dans une instance de la classe.
  • Linq 2 xml
  • XmlTextReader.
  • XmlDocument
  • XPathDocument (accès en lecture seule)
eglasius
la source
2
En fait, XmlReader.Create au lieu d'utiliser directement XmlTextReader, depuis .NET 2.0.
John Saunders
7

Linq en XML.

De plus, VB.NET a une bien meilleure prise en charge de l'analyse XML via le compilateur que C #. Si vous avez l'option et le désir, vérifiez-le.


la source
"Tout faux"? Pas exact, je pense, à moins que cette déclaration ne soit plaisantante. L'OP n'a fourni aucune information. sur la version .NET sur laquelle il travaille.
Cerebrus
1
Hé, ouais. C'était en plaisantant, mais je ne suis pas drôle, alors je l'ai retiré.
7

Vous pouvez utiliser un DataSet pour lire des chaînes XML.

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

L'afficher pour des informations.

prasanna venkatesh
la source
très bien! c'est le moyen le plus rapide que j'ai trouvé pour partager des informations à partir des colonnes xml sql et .net !!
elle0087
Pas idéal lorsque vous avez plusieurs niveaux, car il semble mettre chaque niveau dans sa propre table dans l'ensemble de données.
Lenny K
C'est encore bien pour ça même. Je suppose que cela dépend vraiment de l'apparence réelle de vos données et du nombre de couches profondes que vous recherchez.
user2366842
2

Consultez la classe XmlTextReader par exemple.

Frederik Gheysels
la source
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;
            }
        }
    }

Vous pouvez éviter la première instruction et simplement spécifier le nom du chemin dans le constructeur de XmlTextReader.

Vishal Kotak
la source
0

Il existe différentes manières, selon l'endroit où vous souhaitez vous rendre. XmlDocument est plus léger que XDocument, mais si vous souhaitez vérifier de façon minimaliste qu'une chaîne contient du XML, l'expression régulière est probablement le choix le plus rapide et le plus léger que vous puissiez faire. Par exemple, j'ai implémenté des tests de fumée avec SpecFlow pour mon API et je souhaite tester si l'un des résultats dans un XML valide - alors j'utiliserais une expression régulière. Mais si j'ai besoin d'extraire des valeurs de ce XML, je l'analyserais avec XDocument pour le faire plus rapidement et avec moins de code. Ou j'utiliserais XmlDocument si je dois travailler avec un gros XML (et parfois je travaille avec des XML d'environ 1M lignes, encore plus); alors je pourrais même le lire ligne par ligne. Pourquoi? Essayez d'ouvrir plus de 800 Mo en octets privés dans Visual Studio; même en production, vous ne devriez pas avoir d'objets de plus de 2 Go. Vous pouvez avec un twerk, mais vous ne devriez pas. Si vous deviez analyser un document, qui contient BEAUCOUP de lignes, alors ces documents seraient probablement CSV.

J'ai écrit ce commentaire, car je vois un tas d'exemples avec XDocument. XDocument n'est pas bon pour les gros documents, ou lorsque vous souhaitez uniquement vérifier si le contenu est XML valide. Si vous souhaitez vérifier si le XML lui-même est logique, vous avez besoin d'un schéma.

J'ai également rejeté la réponse suggérée, car je pense qu'elle a besoin des informations ci-dessus en elle-même. Imaginez que je dois vérifier si 200M de XML, 10 fois par heure, est du XML valide. XDocument gaspillera un lof de ressources.

prasanna venkatesh indique également que vous pouvez essayer de remplir la chaîne dans un ensemble de données, cela indiquera également un code XML valide.

nkalfov
la source