Как анализировать XML-файлы? [закрыто]

492

Есть ли простой метод анализа файлов XML в C #? Если так, то?

domoaringatoo
источник
Вы можете использовать эту реализацию: stackoverflow.com/a/34813985/5784646
Eulogy
Хорошо, я снова открыл это. Дубликат был решением для чтения XML, где речь идет о разборе файлов XML. Posssible дубликат можно увидеть в вопросы редактирования истории пс @GeorgeStocker
Джереми Томпсон
1
@JeremyThompson Одна из причин, почему это был дубликат, - у другого вопроса есть намного лучший ответ. Верхний ответ, являющийся простым ответом «только ссылка», бесполезен.
Джордж Стокер
1
@ GeorgeStocker вопросы достаточно разные, чтобы сосуществовать, и оба имеют отличные ответы, плюс принятые используют разные технологии. Вот почему я проголосовал за то, чтобы мы оставили это открытым, я знаю, что это общепринятая ссылка - только ссылка, но она написана в MSDN и была написана в то время, когда это было неприемлемо. Надеюсь, побочный эффект повторного открытия немного подбодрит Джона, прочитайте его профиль . Во всяком случае ура.
Джереми Томпсон

Ответы:

245

Я бы использовал LINQ to XML, если вы используете .NET 3.5 или выше.

Джон Галлоуэй
источник
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, который в некоторых случаях намного удобнее, чем интерфейсы сериализации. Если вам нужен один конкретный элемент, вы можете получить доступ к дочерним элементам с помощью indexer: xmlDoc ["Root"], и их можно объединить в цепочку: xmlDoc ["Root"] ["Folder"] ["Item"], чтобы найти иерархия (хотя разумно подтвердить, что эти элементы действительно существуют)
Джейсон Уильямс
1
InnerTextздесь получает значение этого узла, объединенного со всеми значениями дочерних узлов - верно? Кажется странным хотеть.
Дон Чидл
17
Программист со списком подруг? Shenanigans!
Э. ван Путтен
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 # является схемой, украшенной атрибутами C #.
Марк Лаката
25

Если вы обрабатываете большой объем данных (много мегабайт), то вы хотите использовать XmlReaderдля потокового анализа XML.

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

Конечно, если вам все равно нужны все данные в памяти, у вас может не быть большого выбора.

Саймон Стил
источник
18

Используйте XmlTextReader, XmlReader, XmlNodeReaderи System.Xml.XPathпространство имен. И ( XPathNavigator, XPathDocument, XPathExpression, XPathnodeIterator).

Обычно XPathоблегчает чтение XML, что вы можете искать.

Винко Врсалович
источник
2
К вашему сведению, вы не должны использовать new XmlTextReader()или new XmlTextWriter(). Они устарели с .NET 2.0. Используйте XmlReader.Create()или XmlWriter.Create()вместо.
Джон Сондерс
10

Я только недавно был обязан работать над приложением, которое занималось разбором XML-документа, и я согласен с Джоном Гэллоуэем, что подход, основанный на LINQ to 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 без проблем!

PJRobot
источник
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 Serializer в .NET очень ограничен.

  • Не поддерживает сериализацию класса с циклической ссылкой или класса со свойством интерфейса,
  • Не поддерживает словари,
  • Там нет механизма для чтения старой версии XML,
  • Если вы хотите создать собственный сериализатор, ваш класс должен наследоваться от IXmlSerializable. Это означает, что ваш класс не будет классом POCO,
  • Не поддерживает IoC.

ExtendedXmlSerializer может сделать это и многое другое.

ExtendedXmlSerializer поддерживает .NET 4.5 или выше и .NET Core . Вы можете интегрировать его с WebApi и AspCore.

Wojtpl2
источник
1

Вы можете использовать XmlDocument и для манипулирования или извлечения данных из атрибутов вы можете Linq для классов XML.

шаишав шукла
источник