Jak analizuje się pliki XML? [Zamknięte]

492

Czy istnieje prosta metoda analizowania plików XML w języku C #? Jeśli tak to co?

domoaringatoo
źródło
możesz użyć tej implementacji: stackoverflow.com/a/34813985/5784646
Eulogy
Ok, otworzyłem to ponownie. Duplikat był rozwiązaniem czytnika XML, w którym chodzi o parsowanie plików XML. Posssible duplikat widać w pytaniach edycji historia ps @GeorgeStocker
Jeremy Thompson
1
@JeremyThompson Jednym z powodów, dla których był to duplikat, jest to, że drugie pytanie ma znacznie lepszą odpowiedź. Najlepsza odpowiedź, będąca prostą odpowiedzią „tylko link”, nie jest przydatna.
George Stocker
1
@GeorgeStocker pytania są wystarczająco różne, aby współistnieć i oba mają świetne odpowiedzi, a te zaakceptowane wykorzystują różne technologie. Właśnie dlatego głosowałem, że zostawiamy to otwarte, wiem, że ten zaakceptowany jest tylko linkiem, ale jest to MSDN i został napisany wcześniej, co było niedopuszczalne, mam nadzieję, że efekt uboczny ponownego otwarcia rozweseli nieco Jona, przeczytaj jego profil . W każdym razie na zdrowie.
Jeremy Thompson

Odpowiedzi:

245

Chciałbym użyć LINQ do XML , jeśli jesteś w .NET 3.5 lub wyższej.

Jon Galloway
źródło
314

To jest bardzo proste. Wiem, że są to standardowe metody, ale możesz stworzyć własną bibliotekę, aby poradzić sobie z tym znacznie lepiej.

Oto kilka przykładów:

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

Ponadto istnieje kilka innych metod pracy. Na przykład tutaj . I myślę, że nie ma jednej najlepszej metody, aby to zrobić; zawsze musisz sam to wybrać, co jest dla Ciebie najbardziej odpowiednie.

Lukas Šalkauskas
źródło
47
+1 za wzmiankę o XmlDocument, który w niektórych przypadkach jest znacznie wygodniejszy niż interfejsy serializacji. Jeśli szukasz jednego określonego elementu, możesz uzyskać dostęp do elementów podrzędnych za pomocą indeksu: xmlDoc [„Root”], a te mogą być powiązane: xmlDoc [„Root”] [„Folder”] [„Item”], aby wykopać hierarchia (choć rozsądne jest potwierdzenie, że te elementy faktycznie istnieją)
Jason Williams
1
InnerTexttutaj dostaje się wartość tego węzła, połączoną ze wszystkimi wartościami węzłów potomnych - prawda? Wydaje się, że to dziwna rzecz.
Don Cheadle,
17
Programista z listą koleżanek? Kombinowanie!
E. van Putten,
1
@ E.vanPutten nie w dzisiejszych czasach. To nie jest Revenge of the Nerds
user4052054
@DonCheadle Jeśli nie spodziewasz się, że będą jakieś węzły podrzędne, zwrócę InnerTextpo prostu wartość węzła - właśnie tego (ja i ​​prawdopodobnie wszyscy inni czytający to pytanie) analizuję XML w pierwszej kolejności.
F1Krazy
48

Użyj dobrego schematu XSD, aby utworzyć zestaw klas za pomocą xsd.exe, a następnie użyj, XmlSerializeraby utworzyć drzewo obiektów z pliku XML i odwrotnie. Jeśli masz kilka ograniczeń dotyczących swojego modelu, możesz nawet spróbować utworzyć bezpośrednie mapowanie między klasami modelu a XML za pomocą atrybutów Xml *.

Jest artykuł wprowadzający na temat serializacji XML na MSDN.

Wskazówka dotycząca wydajności: Budowa XmlSerializerjest kosztowna. Zachowaj odniesienie do swojego XmlSerializerwystąpienia, jeśli zamierzasz parsować / zapisywać wiele plików XML.

David Schmitt
źródło
5
Dobrym przykładem jest „Przykład zamówienia zakupu” w środku tego przykładu z Microsoft. msdn.microsoft.com/en-us/library/58a18dwa.aspx . Unikasz tworzenia schematu - twoja klasa c # jest schematem ozdobionym atrybutami C #.
Mark Lakata,
25

Jeśli przetwarzasz dużą ilość danych (wiele megabajtów), to chcesz używać XmlReaderdo strumieniowego analizowania XML.

Cokolwiek innego ( XPathNavigator, XElement, XmlDocumenta nawet XmlSerializerjeśli zachować pełną wygenerowany wykres obiektu) spowoduje wysokie zużycie pamięci , a także bardzo powolny czas ładowania.

Oczywiście, jeśli i tak potrzebujesz wszystkich danych w pamięci, możesz nie mieć dużego wyboru.

Simon Steele
źródło
10

Niedawno zostałem zmuszony do pracy nad aplikacją, która wymagała parsowania dokumentu XML i zgadzam się z Jonem Gallowayem, że moim zdaniem podejście oparte na LINQ to XML jest najlepsze. Musiałem jednak trochę kopać, aby znaleźć użyteczne przykłady, więc bez zbędnych ceregieli, oto kilka!

Wszelkie komentarze są mile widziane, ponieważ ten kod działa, ale może nie być idealny. Chciałbym dowiedzieć się więcej na temat analizowania XML dla tego projektu!

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

Dzięki tym funkcjom byłem w stanie przeanalizować dowolny element i dowolny atrybut z pliku XML, nie ma problemu!

PJRobot
źródło
8

Jeśli używasz .NET 2.0, spróbuj XmlReaderi jego podklasy XmlTextReaderoraz XmlValidatingReader. Zapewniają szybki, lekki (użycie pamięci itp.), Tylko do przodu sposób parsowania pliku XML.

Jeśli potrzebujesz XPathmożliwości, wypróbuj XPathNavigator. Jeśli potrzebujesz całego dokumentu w pamięci, spróbuj XmlDocument.

Popiół
źródło
7

Ponadto możesz użyć selektora XPath w następujący sposób (łatwy sposób wyboru określonych węzłów):

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

dokumentacja

Joel Harkes
źródło
6

Nie jestem pewien, czy istnieje „najlepsza praktyka do analizowania XML”. Istnieje wiele technologii dostosowanych do różnych sytuacji. Wybór sposobu zależy od konkretnego scenariusza.

Możesz iść z LINQ do XML , XmlReader, XPathNavigatora nawet wyrażeń regularnych. Jeśli opracujesz swoje potrzeby, mogę spróbować podać kilka sugestii.

aku
źródło
3
Wyrażenie regularne dla xml. Ty potworze.
będzie
3

Możesz parsować XML za pomocą tej biblioteki System.Xml.Linq. Poniżej znajduje się przykładowy kod użyty do parsowania pliku XML

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
źródło
1

Możesz użyć ExtendedXmlSerializer do serializacji i deserializacji.

Instalacja Możesz zainstalować ExtendedXmlSerializer z nuget lub uruchomić następującą komendę:

Install-Package ExtendedXmlSerializer

Serializacja:

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

Deserializacja

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

Standardowy serializator XML w .NET jest bardzo ograniczony.

  • Nie obsługuje serializacji klasy z odwołaniem cyklicznym lub klasy z właściwością interfejsu,
  • Nie obsługuje słowników,
  • Nie ma mechanizmu odczytu starej wersji XML,
  • Jeśli chcesz utworzyć niestandardowy serializator, twoja klasa musi dziedziczyć po IXmlSerializable. Oznacza to, że twoja klasa nie będzie klasą POCO,
  • Nie obsługuje IoC.

ExtendedXmlSerializer może to zrobić i wiele więcej.

Obsługa ExtendedXmlSerializer .NET 4.5 lub nowszy i .NET Core . Możesz zintegrować go z WebApi i AspCore.

Wojtpl2
źródło
1

Możesz używać XmlDocument, a do manipulowania danymi lub ich pobierania z atrybutów możesz użyć Linq do klas XML.

Shaishav Shukla
źródło