Як один розбір файлів XML? [зачинено]


492

Чи є простий метод розбору XML-файлів у C #? Якщо так, то що?


ви можете використовувати цю реалізацію: stackoverflow.com/a/34813985/5784646
Eulogy

Добре, я знову відкрив це. Дублікат був рішенням XML Reader, де мова йде про розбір файлів XML. Можливий дублікат можна побачити в питаннях редагування питань ps @GeorgeStocker
Jeremy Thompson

1
@JeremyThompson Однією з причин, чому це було дублікатом, є інше питання, яке має набагато кращу відповідь. Верхня відповідь - це проста відповідь "лише за посиланням", не корисна.
Джордж Стокер

1
@GeorgeStocker питання досить різні, щоб співіснувати, і обидва мають чудові відповіді, плюс прийняті використовують різні технології. Ось чому я голосував, ми залишаємо це відкритим, я знаю, що це прийняте є лише посиланням, але це MSDN і було написано в той час, як це було неприйнятним, сподіваємось, побічний ефект від повторного відкриття трохи підбадьорив Джона, прочитайте його профіль . Все одно ура.
Джеремі Томпсон

Відповіді:



314

Це дуже просто. Я знаю, що це стандартні методи, але ви можете створити власну бібліотеку, щоб вирішити це набагато краще.

Ось кілька прикладів:

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

Також є деякі інші методи роботи. Наприклад, ось . І я думаю, що немає жодного найкращого методу для цього; завжди потрібно вибирати його самостійно, що для вас найбільше підходить.


47
+1 для згадування XmlDocument, що набагато зручніше, ніж інтерфейси серіалізації в деяких випадках. Якщо ви користуєтесь одним певним елементом, ви можете отримати доступ до дочірніх елементів за допомогою індексатора: xmlDoc ["Root"], і вони можуть бути приковані: xmlDoc ["Root"] ["Folder"] ["Item"]), щоб викопати ієрархія (хоча доцільно підтвердити, що ці елементи існують насправді)
Джейсон Вільямс

1
InnerTextтут отримується значення цього вузла, з'єднане з усіма значеннями дочірніх вузлів - так? Здається, що щось дивно хочеться.
Дон Чідл

17
Програміст зі списком подруг? Шенанігани!
Е. ван Путтен

1
@ E.vanPutten не в цей день і вік. Це не Помста
Нердів

@DonCheadle Якщо ви не очікуєте, що там будуть якісь дочірні вузли, тоді InnerTextви просто повернете значення вузла - саме це я (і, мабуть, усі, хто читає це питання), розбирає XML, щоб знайти в першу чергу.
F1Krazy

48

Скористайтеся хорошою схемою XSD, щоб створити набір класів за допомогою xsd.exe і використовувати XmlSerializerдля створення дерева об'єктів із XML і навпаки. Якщо у вас мало обмежень на вашу модель, ви навіть можете спробувати створити пряме відображення між вами модельними класами та XML з атрибутами Xml *.

Є вступна стаття про серіалізацію XML на MSDN.

Порада щодо продуктивності: Побудувати конструкцію XmlSerializerдорого. Зберігайте посилання на свій XmlSerializerпримірник, якщо ви плануєте розбирати / записувати кілька XML-файлів.



5
Хороший приклад - "Приклад замовлення на купівлю" в середині цього прикладу від Microsoft. msdn.microsoft.com/en-us/library/58a18dwa.aspx . Вам не доведеться створювати схему - ваш клас # є схемою, прикрашеною атрибутами C #.
Марк Лаката

25

Якщо ви обробляєте велику кількість даних (багато мегабайт), ви хочете використовувати їх XmlReaderдля потокового розбору XML.

Все інше ( XPathNavigator, XElement, XmlDocumentі навіть XmlSerializerякщо ви тримаєте повний згенерований граф об'єктів) призведе до високого завантаження пам'яті , а також дуже повільне час завантаження.

Звичайно, якщо вам все-таки потрібні всі дані в пам'яті, то можливо у вас не буде великого вибору.


18

Використовуйте XmlTextReader, XmlReader, XmlNodeReaderі System.Xml.XPathпростір імен. І ( XPathNavigator, XPathDocument, XPathExpression, XPathnodeIterator).

Зазвичай XPathполегшує читання XML, що саме ви можете шукати.


2
FYI, ви не повинні використовувати new XmlTextReader()або new XmlTextWriter(). Вони застаріли з .NET 2.0. Використовуйте XmlReader.Create()або XmlWriter.Create()замість цього.
Джон Сондерс

10

Мені нещодавно потрібно було працювати над додатком, який передбачав розбір документа XML, і я погоджуюся з Джоном Галлоуей, що підхід на основі LINQ до XML є, на мій погляд, найкращим. Однак мені довелося трохи копати, щоб знайти корисні приклади, тож без зайвої приналежності ось кілька!

Будь-які коментарі вітаються, оскільки цей код працює, але може бути не ідеальним, і я хотів би дізнатися більше про розбір XML для цього проекту!

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

За допомогою цих функцій я зміг розібрати будь-який елемент та будь-який атрибут із XML-файлу взагалі без проблем!


8

Якщо ви використовуєте .NET 2.0, спробуйте XmlReaderі його підкласи XmlTextReader, і XmlValidatingReader. Вони забезпечують швидкий, легкий (використання пам'яті тощо), єдиний вперед спосіб розбору XML-файлу.

Якщо вам потрібні XPathможливості, спробуйте XPathNavigator. Якщо вам потрібен весь документ у пам'яті, спробуйте XmlDocument.


7

Крім того, ви можете використовувати селектор XPath наступним чином (простий спосіб вибору конкретних вузлів):

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

документація


6

Я не впевнений, чи існує "найкраща практика для розбору XML". Існують численні технології, що підходять для різних ситуацій. Який спосіб використовувати, залежить від конкретного сценарію.

Ви можете піти з LINQ до XML , XmlReader, XPathNavigatorабо навіть регулярні вирази. Якщо ви конкретизуєте свої потреби, я можу спробувати дати кілька пропозицій.


3
регекс для xml ти монстр.
буде

3

Ви можете проаналізувати XML за допомогою цієї бібліотеки System.Xml.Linq. Нижче наведено зразок коду, який я використовував для розбору файлу 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;
}

1

Ви можете використовувати ExtendedXmlSerializer для серіалізації та десеріалізації.

Встановлення Ви можете встановити ExtendedXmlSerializer з nuget або виконати таку команду:

Install-Package ExtendedXmlSerializer

Серіалізація:

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

Десеріалізація

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

Стандартний XML-серіалізатор у .NET дуже обмежений.

  • Не підтримує серіалізацію класу з круговою посиланням або клас із властивістю інтерфейсу,
  • Не підтримує словники,
  • Не існує механізму для читання старої версії XML,
  • Якщо ви хочете створити спеціальний серіалізатор, ваш клас повинен успадкувати від IXmlSerializable. Це означає, що ваш клас не буде класом POCO,
  • Не підтримує IoC.

ExtendedXmlSerializer може зробити це та багато іншого.

Розширена підтримкаXmlSerializer .NET 4.5 або новішої версії та .NET Core . Ви можете інтегрувати його з WebApi та AspCore.


1

Ви можете використовувати XmlDocument, а також для маніпулювання або отримання даних з атрибутів ви можете Linq до XML-класів.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.