Jak czytać i analizować plik XML w C #?

362

Jak czytać i analizować plik XML w C #?

Gajendra
źródło
2
Najprostszym rozwiązaniem jest użycie LINQ to XML. Zobacz mój przykład.
Konstantin Tarkus

Odpowiedzi:

480

XmlDocument do odczytu XML z ciągu znaków lub z pliku.

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

lub

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

następnie znajdź pod nim węzeł, czyli tak

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

lub

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

następnie przeczytaj tekst w tym węźle w ten sposób

string text = node.InnerText;

lub przeczytaj atrybut

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

Zawsze sprawdzaj wartość NULL w atrybutach [„coś”], ponieważ będzie ona pusta, jeśli atrybut nie istnieje.

Wolf5
źródło
1
Prawidłowe, ale Linq to XML jest znacznie ładniejszy.
Finglas
3
Chociaż mówisz, że to „ładniejsze”, jest jeszcze jedna wada w porównaniu z LINQ? Osobiście uznałem tę metodę za najprostszą, przynajmniej dla moich potrzeb.
Kolors
6
Napisałem to, zanim zacząłem używać LINQ. LINQ jest ładny i może mieć łatwiejszą czytelność. Obecnie najczęściej używam LINQ. Ale niektóre komponenty potrzebują obiektów XML starego stylu, więc od czasu do czasu są używane. Poleciłbym wypróbowanie zarówno „starego stylu” tutaj, jak i LINQ i zobaczenie, co ci pasuje.
Wolf5
1
Czy XmlNode node = XmlDocument.Docu...linia nie powinna tak naprawdę być XmlNode = doc.Docu...? Dlaczego zmieniono odpowiedź i doc.usunięto?
wasatchwizard
Prawdziwe. Nie mam pojęcia, dlaczego to zmieniłem ... Naprawię.
Wolf5
217

Przykład 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);
}

Odniesienie : LINQ do XML w MSDN

Konstantin Tarkus
źródło
16
XDocument.Parse („<xml> coś </xml>”); na ciąg.
Wolf5
2
Ludzie, którzy nie uwzględniają włączeń, są wredni, dzięki za odpowiedź :)
Gabriel Garcia
@GabrielGarcia prawda, czasami początkujący utknął w błędzie brakującym to błąd
Anonimowy
1
jakie są odpowiednie obejmuje?
powiedzmy
18

Oto aplikacja, którą napisałem do czytania map witryn 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()
        {
        }
    }
}

Kod na Paste Bin http://pastebin.com/yK7cSNeY

ajzeffer
źródło
12

Jest wiele sposobów, niektóre:

  • XmlSerializer. użyj klasy ze schematem docelowym, który chcesz odczytać - użyj XmlSerializer, aby załadować dane z pliku Xml do instancji klasy.
  • Linq 2 xml
  • XmlTextReader.
  • XmlDocument
  • XPathDocument (dostęp tylko do odczytu)
eglasius
źródło
2
W rzeczywistości XmlReader.Create zamiast bezpośrednio używać XmlTextReader, ponieważ .NET 2.0.
John Saunders,
7

Linq do XML.

Ponadto VB.NET ma znacznie lepszą obsługę parsowania XML za pośrednictwem kompilatora niż C #. Jeśli masz opcję i pragnienie, sprawdź to.


źródło
"Wszystko źle"? Myślę, że niedokładne, chyba że to oświadczenie było żartem. OP nie podał żadnych informacji. o wersji .NET, nad którą pracuje.
Cerebrus
1
Hej, tak. Żartowałem, ale nie jestem zabawny, więc go usunąłem.
7

Możesz użyć zestawu danych do odczytu ciągów XML.

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

Publikowanie tego ze względu na informacje.

prasanna venkatesh
źródło
bardzo dobrze! jest to najszybszy sposób, w jaki udało mi się udostępnić informacje z kolumn xml sql i .net !!
elle0087
Nie jest to idealne, gdy masz wiele poziomów, ponieważ wydaje się, że umieszczasz każdy poziom w osobnej tabeli w zbiorze danych.
Lenny K
Nawet to jest w porządku. Wydaje mi się, że to naprawdę zależy od tego, jak naprawdę wyglądają twoje dane i od tego, ile warstw danych potrzebujesz.
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;
            }
        }
    }

Możesz uniknąć pierwszej instrukcji i po prostu podać nazwę ścieżki w konstruktorze XmlTextReader.

Vishal Kotak
źródło
0

Istnieją różne sposoby, w zależności od tego, gdzie chcesz się dostać. XmlDocument jest lżejszy niż XDocument, ale jeśli chcesz minimalnie sprawdzić, czy ciąg zawiera XML, to wyrażenie regularne jest prawdopodobnie najszybszym i najlżejszym wyborem, jaki możesz zrobić. Na przykład zaimplementowałem testy dymu z SpecFlow dla mojego API i chciałbym sprawdzić, czy któryś z wyników w jakimkolwiek poprawnym pliku XML - wtedy użyłbym wyrażenia regularnego. Ale jeśli muszę wyodrębnić wartości z tego kodu XML, wówczas przeanalizuję go za pomocą XDocument, aby zrobić to szybciej i przy mniejszej ilości kodu. Albo użyłbym XmlDocument, gdybym musiał pracować z dużym XML-em (a czasami pracuję z XML-em, które mają około 1M linii, a nawet więcej); wtedy mogłem nawet przeczytać to wiersz po wierszu. Dlaczego? Spróbuj otworzyć więcej niż 800 MB w bajtach prywatnych w Visual Studio; nawet podczas produkcji nie powinieneś mieć obiektów większych niż 2 GB. Możesz z twerkerem, ale nie powinieneś. Jeśli musiałbyś parsować dokument, który zawiera DUŻO wierszy, to prawdopodobnie byłby to CSV.

Napisałem ten komentarz, ponieważ widzę mnóstwo przykładów z XDocument. XDocument nie nadaje się do dużych dokumentów lub gdy chcesz tylko sprawdzić, czy zawartość jest poprawna XML. Jeśli chcesz sprawdzić, czy sam XML ma sens, potrzebujesz Schematu.

Głosowałem również za sugerowaną odpowiedzią, ponieważ uważam, że potrzebuje ona powyższych informacji w sobie. Wyobraź sobie, że muszę sprawdzić, czy 200 mln plików XML, 10 razy na godzinę, jest poprawnym plikiem XML. XDocument zmarnuje mnóstwo zasobów.

prasanna venkatesh stwierdza również, że możesz spróbować wypełnić ciąg do zbioru danych, będzie to również wskazywać poprawny kod XML.

nkalfov
źródło