Прогулка дерева XML в С#

Я новичок в .net и С#, поэтому я хочу убедиться, что я использую правильный инструмент для работы.

XML, который я получаю, представляет собой описание дерева каталогов на другом компьютере, поэтому он проходит много уровней. Теперь мне нужно сделать XML и создать структуру объектов (пользовательских классов) и заполнить их информацией из ввода XML, например File, Folder, Tags, Property...

Структура дерева этого XML-ввода делает это, на мой взгляд, основным кандидатом на использование рекурсии для перемещения по дереву.

Есть ли другой способ сделать это в .net 3.5?

Я посмотрел на XmlReaders, но они, кажется, идут по дереву линейным образом, не совсем то, что я ищу...

XML, который я получаю, является частью стороннего api, поэтому находится вне моего контроля и может меняться во фьючерсах.

Я просмотрел Deserialization, но это недостатки (реализация черного ящика, нужно объявлять членов публичным, медленным, работает только для простых объектов...) также выводит его из списка.

Спасибо за ваш вклад в это.

Ответ 1

Я бы использовал классы XLINQ в System.Xml.Linq(это пространство имен и сборка, которые вам нужно будет ссылаться). Загрузите XML и XDocument:

XDocument doc = XDocument.Parse(someString);

Затем вы можете использовать рекурсию или петлю псевдорекурсии для итерации по дочерним узлам. Вы можете выбрать дочерние узлы, например:

//if Directory is tag name of Directory XML
//Note: Root is just the root XElement of the document
var directoryElements = doc.Root.Elements("Directory"); 

//you get the idea
var fileElements = doc.Root.Elements("File"); 

Переменные directoryElements и fileElements будут IEnumerable-типами, что означает, что вы можете использовать что-то вроде foreach для прокрутки всех элементов. Один из способов создания элементов - это что-то вроде этого:

List<MyFileType> files = new List<MyFileType>();

foreach(XElelement fileElement in fileElements)
{
  files.Add(new MyFileType()
    {     
      Prop1 = fileElement.Element("Prop1"), //assumes properties are elements
      Prop2 = fileElement.Element("Prop2"),
    });
}

В этом примере MyFileType - это тип, который вы создали для представления файлов. Это немного грубая атака, но она выполнит свою работу.

Если вы хотите использовать XPath, вам нужно будет использовать System.Xml.XPath.


Примечание по System.Xml vs System.Xml.Linq

Существует несколько классов XML, которые были в .Net с 1.0 дня. Они живут (в основном) в System.Xml. В .Net 3.5 в System.Xml.Linq был выпущен замечательный новый набор классов XML. Я не могу переоценить, насколько они лучше работают, чем старые классы в System.Xml. Я бы настоятельно рекомендовал их любому программисту .Net, и особенно кому-то просто попав в .Net/С#.

Ответ 2

XmlReader не является особо дружественным API. Если вы можете использовать .NET 3.5, то лучше всего будет загружать LINQ to XML. Вы можете легко использовать рекурсию с этим.

В противном случае XmlDocument по-прежнему будет делать трюк... чуть менее приятно.

Ответ 3

Это проблема, которая очень подходит для рекурсии.

Чтобы подробнее рассказать о том, что сказал другой плакат, вы захотите начать загрузку XML в файл System.Xml.XmlDocument(используя LoadXml или Load).

Вы можете получить доступ к корню дерева с помощью свойства XmlDocument.DocumentElement и получить доступ к дочерним элементам каждого из node с помощью свойства ChildNodes. Ребенок-узлы возвращают коллекцию, а когда коллекция имеет размер 0, вы знаете, что достигнете своего базового варианта.

Использование LINQ также является хорошим вариантом, но я не могу подробно остановиться на этом решении, потому что я не специалист по LINQ.

Как сказал Джон, XmlReader не очень дружелюбен. Если у вас возникнут проблемы с первичными функциями, вы можете захотеть изучить его, но если вы просто хотите выполнить эту работу, перейдите в XmlDocument/ChildNodes, используя рекурсию.

Ответ 4

Загрузите XML в XMLDocument. Затем вы можете выполнить XMLDocuments DOM с помощью рекурсии.

Возможно, вы захотите также изучить шаблон метода factory для создания ваших классов, здесь будет очень полезно.