Wie analysiert man XML-Dateien? [geschlossen]

492

Gibt es eine einfache Methode zum Parsen von XML-Dateien in C #? Wenn ja, was?

Domoaringatoo
quelle
Sie könnten diese Implementierung verwenden: stackoverflow.com/a/34813985/5784646
Eulogy
Ok, ich habe das wieder geöffnet. Das Duplikat war eine XML Reader-Lösung, bei der es um das Parsen von XML-Dateien geht. Das mögliche Duplikat kann in den Fragen gesehen werden. Verlauf bearbeiten ps @GeorgeStocker
Jeremy Thompson
1
@JeremyThompson Einer der Gründe, warum dies ein Duplikat war, ist, dass die andere Frage eine viel bessere Antwort hat. Die Top-Antwort, die eine einfache "Nur Link" -Antwort ist, ist nicht nützlich.
George Stocker
1
@GeorgeStocker Die Fragen sind unterschiedlich genug, um nebeneinander zu existieren, und beide haben großartige Antworten. Außerdem akzeptieren die akzeptierten unterschiedliche Technologien. Aus diesem Grund habe ich dafür gestimmt, dass wir dies offen lassen. Ich weiß, dass dieses akzeptierte nur ein Link ist, aber es ist MSDN und wurde zu einem Zeitpunkt geschrieben, bevor dies nicht akzeptabel war. Hoffentlich macht ein Nebeneffekt der Wiedereröffnung Jon ein bisschen munter, lesen Sie sein Profil . Wie auch immer, Prost.
Jeremy Thompson

Antworten:

314

Es ist sehr einfach. Ich weiß, dass dies Standardmethoden sind, aber Sie können Ihre eigene Bibliothek erstellen, um damit viel besser umzugehen.

Hier sind einige Beispiele:

XmlDocument xmlDoc= new XmlDocument(); // Create an XML document object
xmlDoc.Load("yourXMLFile.xml"); // Load the XML document from the specified file

// Get elements
XmlNodeList girlAddress = xmlDoc.GetElementsByTagName("gAddress");
XmlNodeList girlAge = xmlDoc.GetElementsByTagName("gAge"); 
XmlNodeList girlCellPhoneNumber = xmlDoc.GetElementsByTagName("gPhone");

// Display the results
Console.WriteLine("Address: " + girlAddress[0].InnerText);
Console.WriteLine("Age: " + girlAge[0].InnerText);
Console.WriteLine("Phone Number: " + girlCellPhoneNumber[0].InnerText);

Es gibt auch einige andere Methoden , mit denen Sie arbeiten können. Zum Beispiel hier . Und ich denke, es gibt keine beste Methode, um dies zu tun; Sie müssen es immer selbst auswählen, was für Sie am besten geeignet ist.

Lukas Šalkauskas
quelle
47
+1 für die Erwähnung von XmlDocument, das in einigen Fällen viel praktischer ist als Serialisierungsschnittstellen. Wenn Sie nach einem bestimmten Element suchen, können Sie mit dem Indexer auf untergeordnete Elemente zugreifen: xmlDoc ["Root"], und diese können verkettet werden: xmlDoc ["Root"] ["Folder"] ["Item"], um das zu durchsuchen Hierarchie (obwohl es sinnvoll ist zu überprüfen, ob diese Elemente tatsächlich existieren)
Jason Williams
1
InnerTextHier wird der Wert dieses Knotens abgerufen, der mit allen Werten der untergeordneten Knoten verknüpft ist - richtig? Scheint seltsam zu sein.
Don Cheadle
17
Ein Programmierer mit einer Liste von Freundinnen? Shenanigans!
E. van Putten
1
@ E.vanPutten nicht in der heutigen Zeit. Dies ist nicht die Rache der Nerds
user4052054
@DonCheadle Wenn Sie nicht erwarten, dass untergeordnete Knoten vorhanden sind, InnerTextwird nur der Knotenwert zurückgegeben. Dies ist es, was ich (und wahrscheinlich alle anderen, die diese Frage lesen) das XML analysieren, um es zuerst zu finden.
F1Krazy
48

Verwenden Sie ein gutes XSD-Schema , um eine Reihe von Klassen mit xsd.exeXmlSerializer zu erstellen, und verwenden Sie a , um einen Objektbaum aus Ihrem XML zu erstellen und umgekehrt. Wenn Sie nur wenige Einschränkungen für Ihr Modell haben, können Sie sogar versuchen, eine direkte Zuordnung zwischen Ihren Modellklassen und dem XML mit den Xml * -Attributen zu erstellen.

Es gibt einen Einführungsartikel zur XML-Serialisierung auf MSDN.

Leistungstipp: Der Bau eines XmlSerializerist teuer. Behalten Sie einen Verweis auf Ihre XmlSerializerInstanz bei, wenn Sie mehrere XML-Dateien analysieren / schreiben möchten.

David Schmitt
quelle
5
Ein gutes Beispiel ist das "Bestellbeispiel" in der Mitte dieses Beispiels von Microsoft. msdn.microsoft.com/en-us/library/58a18dwa.aspx . Sie müssen kein Schema erstellen - Ihre c # -Klasse ist das Schema, das mit C # -Attributen geschmückt ist.
Mark Lakata
25

Wenn Sie eine große Datenmenge (viele Megabyte) verarbeiten, möchten Sie XmlReaderdie XML-Analyse streamen.

Alles andere ( XPathNavigator, XElement, XmlDocumentund auch , XmlSerializerwenn Sie die volle erzeugte Objektgraphen halten) wird in Folge hohe Speicherauslastung und auch eine sehr lange Ladezeit.

Wenn Sie ohnehin alle Daten im Speicher benötigen, haben Sie möglicherweise nicht viel Auswahl.

Simon Steele
quelle
10

Ich musste erst kürzlich an einer Anwendung arbeiten, bei der ein XML-Dokument analysiert wurde, und ich stimme Jon Galloway zu, dass der auf LINQ to XML basierende Ansatz meiner Meinung nach der beste ist. Ich musste jedoch ein wenig graben, um brauchbare Beispiele zu finden, also hier ohne weiteres ein paar!

Kommentare sind willkommen, da dieser Code funktioniert, aber möglicherweise nicht perfekt ist. Ich würde gerne mehr über das Parsen von XML für dieses Projekt erfahren!

public void ParseXML(string filePath)  
{  
    // create document instance using XML file path
    XDocument doc = XDocument.Load(filePath);

    // get the namespace to that within of the XML (xmlns="...")
    XElement root = doc.Root;
    XNamespace ns = root.GetDefaultNamespace();

    // obtain a list of elements with specific tag
    IEnumerable<XElement> elements = from c in doc.Descendants(ns + "exampleTagName") select c;

    // obtain a single element with specific tag (first instance), useful if only expecting one instance of the tag in the target doc
    XElement element = (from c in doc.Descendants(ns + "exampleTagName" select c).First();

    // obtain an element from within an element, same as from doc
    XElement embeddedElement = (from c in element.Descendants(ns + "exampleEmbeddedTagName" select c).First();

    // obtain an attribute from an element
    XAttribute attribute = element.Attribute("exampleAttributeName");
}

Mit diesen Funktionen konnte ich jedes Element und jedes Attribut aus einer XML-Datei problemlos analysieren!

PJRobot
quelle
8

Wenn Sie .NET 2.0 verwenden, versuchen Sie es mit XmlReaderseinen Unterklassen XmlTextReaderund XmlValidatingReader. Sie bieten eine schnelle, einfache (Speicherauslastung usw.) Möglichkeit, eine XML-Datei nur vorwärts zu analysieren.

Wenn Sie XPathFunktionen benötigen , probieren Sie die XPathNavigator. Wenn Sie das gesamte Dokument im Speicher benötigen, versuchen Sie es XmlDocument.

Asche
quelle
7

Zusätzlich können Sie den XPath-Selektor folgendermaßen verwenden (einfache Auswahl bestimmter Knoten):

XmlDocument doc = new XmlDocument();
doc.Load("test.xml");

var found = doc.DocumentElement.SelectNodes("//book[@title='Barry Poter']"); // select all Book elements in whole dom, with attribute title with value 'Barry Poter'

// Retrieve your data here or change XML here:
foreach (XmlNode book in nodeList)
{
  book.InnerText="The story began as it was...";
}

Console.WriteLine("Display XML:");
doc.Save(Console.Out);

die Dokumentation

Joel Harkes
quelle
6

Ich bin nicht sicher, ob "Best Practice für das Parsen von XML" existiert. Es gibt zahlreiche Technologien, die für unterschiedliche Situationen geeignet sind. Welche Verwendung verwendet wird, hängt vom konkreten Szenario ab.

Sie können gehen mit LINQ to XML , XmlReader, XPathNavigatoroder sogar reguläre Ausdrücke. Wenn Sie Ihre Bedürfnisse näher erläutern, kann ich versuchen, einige Vorschläge zu machen.

aku
quelle
3
Regex für XML. du Monster.
wird
3

Sie können das XML mithilfe dieser Bibliothek analysieren System.Xml.Linq. Unten finden Sie den Beispielcode, mit dem ich eine XML-Datei analysiert habe

public CatSubCatList GenerateCategoryListFromProductFeedXML()
{
    string path = System.Web.HttpContext.Current.Server.MapPath(_xmlFilePath);

    XDocument xDoc = XDocument.Load(path);

    XElement xElement = XElement.Parse(xDoc.ToString());


    List<Category> lstCategory = xElement.Elements("Product").Select(d => new Category
    {
        Code = Convert.ToString(d.Element("CategoryCode").Value),
        CategoryPath = d.Element("CategoryPath").Value,
        Name = GetCateOrSubCategory(d.Element("CategoryPath").Value, 0), // Category
        SubCategoryName = GetCateOrSubCategory(d.Element("CategoryPath").Value, 1) // Sub Category
    }).GroupBy(x => new { x.Code, x.SubCategoryName }).Select(x => x.First()).ToList();

    CatSubCatList catSubCatList = GetFinalCategoryListFromXML(lstCategory);

    return catSubCatList;
}
Tapan Kumar
quelle
1

Sie können ExtendedXmlSerializer zum Serialisieren und Deserialisieren verwenden.

Installation Sie können ExtendedXmlSerializer von Nuget aus installieren oder den folgenden Befehl ausführen:

Install-Package ExtendedXmlSerializer

Serialisierung:

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer();
var obj = new Message();
var xml = serializer.Serialize(obj);

Deserialisierung

var obj2 = serializer.Deserialize<Message>(xml);

Der Standard-XML-Serializer in .NET ist sehr begrenzt.

  • Unterstützt keine Serialisierung von Klassen mit Zirkelreferenz oder Klassen mit Schnittstelleneigenschaften.
  • Unterstützt keine Wörterbücher,
  • Es gibt keinen Mechanismus zum Lesen der alten XML-Version.
  • Wenn Sie einen benutzerdefinierten Serializer erstellen möchten, muss Ihre Klasse von IXmlSerializable erben. Dies bedeutet, dass Ihre Klasse keine POCO-Klasse ist.
  • Unterstützt IoC nicht.

ExtendedXmlSerializer kann dies und vieles mehr.

ExtendedXmlSerializer unterstützt .NET 4.5 oder höher und .NET Core . Sie können es in WebApi und AspCore integrieren.

Wojtpl2
quelle
1

Sie können XmlDocument verwenden und zum Bearbeiten oder Abrufen von Daten aus Attributen Linq to XML-Klassen verwenden.

shaishav shukla
quelle