Ходить по дереву XML в C # - PullRequest
       37

Ходить по дереву XML в C #

10 голосов
/ 14 ноября 2008

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

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

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

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

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

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

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

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

Ответы [ 4 ]

22 голосов
/ 15 ноября 2008

Я бы использовал классы 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 против System.Xml.Linq

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

2 голосов
/ 15 ноября 2008

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

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

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

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

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

2 голосов
/ 14 ноября 2008

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

В противном случае XmlDocument все равно справится с задачей ... чуть менее приятно.

1 голос
/ 14 ноября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...