Форматирование родительского и дочернего узлов Treeview, который заполняется файлом XML - PullRequest
1 голос
/ 24 мая 2010

Я очень плохо знаком с xml, поэтому надеюсь, что не задаю здесь глупых вопросов. В настоящее время я работаю над заполнением древовидного представления из файла XML, который не имеет иерархической структуры. В файле XML, который мне дали, дочерний и родительский узлы определены в атрибутах элемента item. Как бы я мог использовать атрибуты для того, чтобы древовидное представление заполнялось в правильном иерархическом порядке. (Пример Мэри Джейн должен быть дочерним узлом Питера Смита). В настоящее время все имена находятся друг под другом.

корень

<item parent_id="0" id="1"><content><name>Peter Smith</name></content></item>
<item parent_id="1" id="2"><content><name>Mary Jane</name></content></item>
<item parent_id="1" id="7"><content><name>Lucy Lu</name></content></item>
<item parent_id="2" id="3"><content><name>Informatics Team</name></content></item>
<item parent_id="3" id="4"><content><name>Sandy Chu</name></content></item>
<item parent_id="4" id="5"><content><name>John Smith</name></content></item>
<item parent_id="5" id="6"><content><name>Jane Smith</name></content></item>

/ корень

Спасибо за вашу помощь, Марина

Ответы [ 2 ]

2 голосов
/ 24 мая 2010

Вот решение, использующее Linq to XML:

    string strXML = @"<root>
        <item parent_id='0' id='1'><content><name>Peter Smith</name></content></item>
        <item parent_id='1' id='2'><content><name>Mary Jane</name></content></item>
        <item parent_id='1' id='7'><content><name>Lucy Lu</name></content></item>
        <item parent_id='2' id='3'><content><name>Informatics Team</name></content></item>
        <item parent_id='3' id='4'><content><name>Sandy Chu</name></content></item>
        <item parent_id='4' id='5'><content><name>John Smith</name></content></item>
        <item parent_id='5' id='6'><content><name>Jane Smith</name></content></item>
        </root>";

    XDocument xDoc = XDocument.Parse(strXML, LoadOptions.None);

    var objData = xDoc.Root.Elements("item").ToList().Select(item =>
        new { id = item.Attribute("id").Value,
              pid = item.Attribute("parent_id").Value,
              tn = new TreeNode(item.Element("content").Element("name").Value)
        }).ToList();

    objData.ForEach(child =>
        {
            var parent = objData.FirstOrDefault(m => m.id == child.pid);
            if (parent != null)
                parent.tn.Nodes.Add(child.tn);
        });
    // Add all nodes with no parent to the TreeView's root:
    objData.Where(n => n.tn.Parent == null).ToList().ForEach(n => treeView1.Nodes.Add(n.tn));
0 голосов
/ 24 мая 2010

Один из возможных алгоритмов: 1) Получить список parent_id узлов как уникальную коллекцию (не забудьте удалить дубликаты из всех коллекций)

2) Получить атрибуты id в коллекции

3) Создать новую пустую коллекцию 'parents'

4) Для каждого элемента в коллекции id, если соответствующий элемент существует в коллекции parent_id, то этот элемент является родительским для некоторого другого элемента. Вы добавляете этот идентификатор в новую коллекцию parents, которую вы создали

5) Получив список родителей, свяжите это с деревом. Это ваши элементы дерева верхнего уровня.

6) После этого вы можете снова просмотреть коллекцию идентификаторов и просто добавить каждый элемент к своему родителю, используя атрибут parent_id

Поймите, что это не самая эффективная реализация, потому что вы перебираете коллекции несколько раз вместо того, чтобы делать все за один проход (алгоритм для которого, безусловно, будет другим). Так что, если коллекции небольшие, то вышеприведенный подход является хорошим. Но если у вас есть десятки тысяч элементов, просмотр коллекций несколько раз может отрицательно сказаться на производительности. Но этот подход быстр и прост в реализации. Так что имейте в виду компромисс.

Кроме того, поскольку вы только читаете XML и не манипулируете им, предпочитайте XMLReader class вместо XMLDocument.

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