none
Заполнение ListView данными из XML # 2 RRS feed

  • Вопрос

  • Создавал тему с тестовым примером. http://social.msdn.microsoft.com/Forums/ru-RU/3f648852-a559-4ccc-874c-49bf85c7d4ce/-listview-xml  выдернуть данные из пробного xml вроде получилось.

    На "боевом" XML файле проделать тоже самое не удается.

    Вот сам XML

    <?xml version="1.0" encoding="UTF-8"?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="412975879231386" build="ALL" modified="2013-04-25T14:51:50.826Z" icon="0" href="Some other text">
        <caption translate="true">Some Text_PARENT</caption>
        <topicref type="topic" id="413135726611570" build="ALL" modified="1899-12-30" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
        <topicref type="topic" id="413119294865986" build="ALL" modified="1899-12-30" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
        <topicref type="topic" id="412975691218237" build="ALL" modified="2013-01-23T15:43:26.109Z" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
      </topicref>
    </map>

    Вот тот же самый код, только элементы называются по-другому (в отличие от тестового примера).

    namespace PopulateListView
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
    
                DataSet ds = new DataSet();
                ds.ReadXml(@"C:\Users\userame\Desktop\some_text\Maps\file.xml");
                ListViewItem item;
                foreach (DataRow dr in ds.Tables["topicref"].Rows)
                {
                    item = new ListViewItem(new string[]
                    { dr["caption"].ToString()});
                    SongsList.Items.Add(item);
                }
            }
    
        }
    }

    При компиляции выдает исключение

    Подскажите, что делаю не так.  И как вообще работает датасет с Xml? 

    Спасибо.

    28 августа 2013 г. 18:48

Ответы

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

    Я готов помочь советом. Я готов помочь кодом. Я даже готов разработать интерфейс. Однако, это тянет уже на оплачиваемую работу, нэ?

    -----

    Допустим, имеется "file.xml":

    <?xml version="1.0" encoding="utf-8" ?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="412975879231386" build="ALL" modified="2013-04-25T14:51:50.826Z" icon="0" href="Some other text">
        <caption translate="true">Some Text_PARENT</caption>
        <topicref type="topic" id="413135726611570" build="ALL" modified="1899-12-30" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
        <topicref type="topic" id="413119294865986" build="ALL" modified="1899-12-30" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
        <topicref type="topic" id="412975691218237" build="ALL" modified="2013-01-23T15:43:26.109Z" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
      </topicref>
    </map>


    и "root.xml":

    <?xml version="1.0" encoding="utf-8" ?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="413175585366877" build="ALL" modified="2013-02-27T17:35:29.922Z" icon="0" href="xmlFilename">
        <caption translate="true">Caption Text</caption>
        <topicref type="topic" id="413205215997365" build="ALL" modified="2013-02-15T16:10:54.298Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
        <topicref type="topic" id="413177176200927" build="ALL" modified="2013-02-12T14:04:23.600Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
        <topicref type="topic" id="413232741190575" build="ALL" modified="2013-02-18T10:01:28.675Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
          <topicref type="topic" id="413236232967992" build="ALL" modified="2013-02-18T10:01:05.083Z" icon="0" href="xmlFilename">
            <caption translate="true">Caption Text</caption>
          </topicref>
          <topicref type="topic" id="413236237162494" build="ALL" modified="2013-02-18T10:01:52.699Z" icon="0" href="xmlFilename">
            <caption translate="true">Caption Text</caption>
          </topicref>
        </topicref>
        <navref href="file.xml" build="ALL" id="413245773596338" modified="2013-02-19T10:07:06.311Z" merge="compile">
          <caption translate="true">Caption Text</caption>
        </navref>
      </topicref>
    </map>


    В атрибуте href путь к файлу.

    Код для обработки:

    using System;
    using System.Linq;
    using System.Windows.Forms;
    using System.Xml.Linq;
    
    namespace WinForm_MSDN_XML
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string path = "root.xml";
                var xDocument = XDocument.Load(path);
    
                // Добавляем первую колонку
                listView1.Columns.Add("XML Content Tree");
    
                // Добавляем колонки с именами, как у атрибутов узла caption (допустимо больше одного)
                foreach (var attr in xDocument.Root.Element("topicref").Element("caption").Attributes())
                    listView1.Columns.Add(attr.Name.LocalName);
    
                // Добавляем колонки с именами, как у атрибутов элемента topicref.
                // То есть у всех таких элементов должно быть одинаковое количество одинаковых атрибутов.
                foreach (var attr in xDocument.Root.Element("topicref").Attributes())
                    listView1.Columns.Add(attr.Name.LocalName);
    
                processXml(path, 0);
    
                listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            }
    
            void processXml(string path, int curDepth)
            {
                var xDocument = XDocument.Load(path);
                int depth = 0;
    
                foreach (var elem in xDocument.Descendants("topicref"))
                {
                    // Глубина вложенности текущего элемента topicref
                    depth = elem.Ancestors().Count() - 1;
    
                    // Отступ для красивого форматирования
                    string indent = new string(' ', (curDepth + depth) * 4);
    
                    // Значение элемента caption с отступом будет в первой колонке
                    string firstSubItem = indent + elem.Element("caption").Value;
                    var item = new ListViewItem(firstSubItem);
    
                    // Значения атрибутов элемента caption
                    var subItems = elem.Element("caption").Attributes().Select(a => a.Value).ToArray();
                    item.SubItems.AddRange(subItems);
    
                    // В остальных колонках будут значения атрибутов текущего элемента topicref
                    subItems = elem.Attributes().Select(a => a.Value).ToArray();
                    item.SubItems.AddRange(subItems);
    
                    listView1.Items.Add(item);
                }
    
                // Обрабатываем файлы, имена которых находятся в атрибуте href узлов navref
                foreach (var elem in xDocument.Descendants("navref"))
                {
                    string fileName = elem.Attribute("href").Value;
                    processXml(fileName, curDepth + depth);
                }
            }
        }
    }

    На форме только ListView.

    Атрибуты узла navref тоже можно показать (сейчас они не показываются), при желании. Однако, show me the desired GUI!

    2 сентября 2013 г. 16:25
  • Вы публикуете скриншот, на котором только дерево, а потом спрашиваете, как атрибуты выводить. Покажите картинку, как именно должен выглядеть желаемый интерфейс.

    Желаемый интерфейс, примерно такой. Его я уже публиковал. 

    Я готов помочь советом. Я готов помочь кодом. Я даже готов разработать интерфейс. Однако, это тянет уже на оплачиваемую работу, нэ?

    Возможно, Вы правы! :) Вы и так, я считаю уделяете достаточно внимания, Поэтому, буду признателен за первые 2 пункта...хватит совета..и немного кода ))) Остальное по Вашему усмотрению :) Я не программист и делаю это не в коммерческих, а в сугубо образовательных целях. За Вашу помощь, в качестве благодарности, с удовольствием проставился бы пивом :))) Но в силу того,что мы скорее всего, живем в разных странах...к сожалению не получится )

    • Помечено в качестве ответа Andrey Langovoy 14 сентября 2013 г. 7:36
    3 сентября 2013 г. 5:33

Все ответы

  • Мне писали в предыдущей теме, что лучше способа с использованием класса DataSet нет. И, как я понимаю, чтобы полностью разобраться с Data Set, нужно перелопатить кучу документации и понять что такое ADO.NET !?

    Может есть альтернативные варианты, как гибко и просто выбрать данные из XML? 

    XQuery - ?

    XPath - ?

    Linq to XML?

    или все таки через Data Set?

    28 августа 2013 г. 19:22
  • Не понятно, зачем вы пытаетесь применить DataSet, если в предыдущей теме было объяснено и, вроде, понято, как использовать XDocument/XElement (основа Linq to Xml).

    DataSet - это набор таблиц DataTable. Таблица, что естественно, предназначена для хранения табличных данных. Приведённый в этой теме документ не является "нормальной" таблицей (из-за вложенности одних узлов topicref в другой). Кстати, в прошлой теме xml-документ с песнями был нормальной таблицей.

    Данные, представленные в виде таблиц очень удобно (и просто) привязывать к компоненту DataGridView (он, собственно, предназначен для отображения именно таблиц). Код элементарный:

    var ds = new DataSet();
    ds.ReadXml("file.xml");
    var dgv = new DataGridView { Parent = this, Dock = DockStyle.Fill };
    dgv.DataSource = ds.Tables[0];

    Если в файле file.xml данные с песнями из прошлой темы, то они корректно отобразятся. Если там данные этой темы, то таблиц в датасете будет уже две. Содержимое второй таблицы можно вывести в датагридвью строкой

    dgv.DataSource = ds.Tables[1];

    Но не думаю, что результат устроит вас.

     

    Теперь переходим к вопросу, как разобрать текущий xml и показать его в ListView. Это тоже несложно, однако всё зависит от того, в каком виде нужно показать данные. Как я уже отмечал, данные одних узлов вложены в другой, поэтому непонятно, как отразить иерархию на плоский ListView. И какой режим View включен у ListView?

    28 августа 2013 г. 22:08
  • > что лучше способа с использованием класса DataSet нет

    Как я уже написал в предыдущем ответе, DataSet/DataTable идеальны для табличных данных. Для нетабличных они не подходят.

    > как я понимаю, чтобы полностью разобраться с Data Set, нужно перелопатить кучу документации и понять что такое ADO.NET !?

    Да. Это обязательно нужно знать, если будете работать с базами данных. Для работы с xml - не обязательно.

    > XQuery - ?

    В платформе .NET нет стандартных средств для работы с xquery, так что отпадает.

    > XPath - ?

    XPath работает довольно медленно.

    > Linq to XML?

    Да, это почти идеальный вариант.

    Есть ещё варианты: XmlDocument - но только в том случае, если вы отлично знаете W3C DOM (весьма убогая, скажу я вам, вещь). Ныне не рекомендуется. Рекомендутся Linq to Xml.

    И последний вариант: XmlReader. Работа с ним считается сложной (хотя зависит от формата данных xml). Но он является единственной альтернативой, когда объём обрабатываемых xml-данных огромен и не влезает целиком в память.

    28 августа 2013 г. 22:19
  • Ваши ответы, каквсегда - шедевральны :)

    На счет структуры XML, Вы правы, имеет некую древовидную структуру, которую я бы хотел отобразить в ListView. TreeView мне наверное не подойдет, т.к. возможно мне нужно будет выводить в тот же ListView еще и значение некоторых атрибутов, а не только текст элемента. У ListView включен режим Details. В конечном итоге, хотелось бы получить в List View , если это возможно, нечто похожее на дерево...т.е. смешать три вью и лист вью.

    Parent Node
    
    Parent Node
    
        Child Node
    
        Child Node
    
            Sub Cild Node
    
        Child Node
    
    Parent Node


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

    Спасибо.


    29 августа 2013 г. 4:19
  • Традиционно, отображение иерархических данных делают как в Проводнике Windows: в TreeView - дерево узлов, а в каком-либо подходящем компоненте рядом - содержимое отдельного узла, выбранного в текущий момент.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using System.Xml.Linq;
    
    namespace WinForm_MSDN_XML
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
                xDocument = XDocument.Load("file.xml");
            }
    
            readonly XDocument xDocument;
    
            private void Form1_Load(object sender, EventArgs e)
            {
                AddNode(treeView1.Nodes, xDocument.Elements());
                treeView1.ExpandAll();
            }
    
            void AddNode(TreeNodeCollection treeNodes, IEnumerable<XElement> elements)
            {
                foreach (var elem in elements)
                {
                    var node = treeNodes.Add(elem.Name.ToString());
    
                    // Сохраняем в свойстве Tag ссылку на xml-элемент,
                    // чтобы извлекать его в методе treeView1_AfterSelect
                    node.Tag = elem;
    
                    AddNode(node.Nodes, elem.Elements());
                }
            }
    
            private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
            {
                listView1.Items.Clear();
                listView1.Columns.Clear();
    
                // Извлекаем xml-элемент из Tag
                XElement elem = (XElement)e.Node.Tag;
    
                // Создаём в ListView колонки с именами как у атрибутов
                foreach (var attr in elem.Attributes())
                    listView1.Columns.Add(attr.Name.LocalName);
    
                // Получаем значения атрибутов
                var subItems = elem.Attributes().Select(a => a.Value).ToArray();
                ListViewItem item = new ListViewItem(subItems);
                
                // Этот невнятный кусок кода нужен для получения текстового значения
                // самого узла, исключаю его дочерние подузлы.
                // Текстовых подузлов может быть несколько, поэтому такие финты, как с коллекцией.
                var textNodes = elem.Nodes().OfType<XText>();
    
                if (textNodes.Any())
                {
                    // Если у узла есть собственное текстовое значение,
                    // то добавляем ещё одну колонку
                    var header = listView1.Columns.Add("Value");
                    // и в эту колонку заносим текст
                    string s = string.Concat(textNodes.Select(t => t.Value));
                    item.SubItems.Add(s);
                }
                // конец невнятного куска кода
    
                listView1.Items.Add(item);
            }
        }
    }

    В данном примере на форме один TreeView и рядом с ним ListView.

    29 августа 2013 г. 18:07
  • Спасибо, попробую Ваш код.

    Как в проводнике виндовс, наверное будет не совсем удобно, т.к. дерево может быть развернуто, а может быть и нет, и чтобы увидеть атрибуты какого-либо узла, нужно на него кликать. По аналогии с проводником, в ListView справа я вижу содержимое того элемента, кот. выбрал в дереве слева.

    В принципе, мне не нужна возможность на форме сворачивать и разворачивать эти узлы. Нужно видеть структуру в целом + сразу видеть атрибуты элементов. Вот примерная картинка того, что хочу получить в итоге. Где-нибуть выше иметь на форме кнопку, при клике на которую откроется FolderBrowserDialog...выбрать папку с XML файлом (не сам файл).

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

    Нажать ОК, и получить такую картинку.

    Имеет ли смысл смотреть в сторону WPF для реализации такой затеи? Мне говорили, что там это сделать проще использованием байндинга!? Просто WPF для меня темный лес )

    Спасибо.

    30 августа 2013 г. 5:28
  • А получилось вот что

    Тоесть, в три вью видим имена элементов, и при выборе элемента видим в лист вью все его атрибуты. Не совсем то что нужно, но уже что-то :)

    Мне в три вью нужно видеть не имя элемента, а его содержимое  <caption>Some Text</caption> т.е. чтобы в три вью было Some Text ну и так далее для других узлов. А уже в лит вью атрибуты...

    Но все же, желаемый результат нарисовал в посте выше.


    30 августа 2013 г. 6:15
  • Мне осталось непонятным, нужен ли универсальный код для любой структуры xml?

    Вот код, в который жёстко забиты имена узлов и предположение, что у каждого узла topicref есть подузел caption.

    private void Form1_Load(object sender, EventArgs e)
    {
        // Добавляем первую колонку
        listView1.Columns.Add("XML Content Tree");
    
        // Добавляем колонки с именами, как у атрибутов элемента topicref.
        // То есть у всех таких элементов должно быть одинаковое количество одинаковых атрибутов.
        foreach (var attr in xDocument.Root.Element("topicref").Attributes())
            listView1.Columns.Add(attr.Name.LocalName);
    
        foreach (var elem in xDocument.Descendants("topicref"))
        {
            // Глубина вложенности текущего элемента topicref
            int depth = elem.Ancestors().Count() - 1;
    
            // Отступ для красивого форматирования
            string indent = new string(' ', depth * 4);
    
            // Значение элемента caption с отступом будет в первой колонке
            string firstSubItem = indent + elem.Element("caption").Value;
            var item = new ListViewItem(firstSubItem);
    
            // В остальных колонках будут значения атрибутов
            var subItems = elem.Attributes().Select(a => a.Value).ToArray();
            item.SubItems.AddRange(subItems);
    
            listView1.Items.Add(item);
        }
    
        listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
    }

    На форме только ListView. XDocument загружается по-прежнему в конструкторе.

    Если нужно, можно и значение атрибута translate узла caption тоже вывести.

    Я могу модифицировать код, чтобы он разбирал и выводил в похожем виде xml со следующей структурой: есть набор узлов с одинаковыми именами (как topicref, но имя любое), у каждого есть набор атрибутов, но нет собственного значения, и у каждого есть подузел (как caption, но имя любое) с собственным значением (атрибуты тоже могут быть).

    Насчёт WPF. Реализовать на нём, конечно, можно. Но суть не изменится. Просто код будет в конверторе байндинга.

    30 августа 2013 г. 16:12
  • Мне осталось непонятным, нужен ли универсальный код для любой структуры xml?

    Да, т.к структура может несколько отличаться. Вот один пример:

    <?xml version="1.0" encoding="UTF-8"?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="412975879231386" build="ALL" modified="2013-04-25T14:51:50.826Z" icon="0" href="xmlFilename">
        <caption translate="true">Caption text</caption>
        <topicref type="topic" id="413135726611570" build="ALL" modified="1899-12-30" icon="0" href="xmlFilename">
          <caption translate="true">Caption text</caption>
        </topicref>
        <topicref type="topic" id="413119294865986" build="ALL" modified="1899-12-30" icon="0" href="xmlFilename">
          <caption translate="true">Caption text</caption>
        </topicref>
        <topicref type="topic" id="412975691218237" build="ALL" modified="2013-01-23T15:43:26.109Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption text</caption>
        </topicref>
        <topicref type="topic" id="412975312357397" build="ALL" modified="2013-01-23T15:43:26.109Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption text</caption>
        </topicref>
        <topicref type="topic" id="412974709678982" build="ALL" modified="2013-01-23T15:43:26.109Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption text</caption>
        </topicref>
        <topicref type="topic" id="414303142783048" build="ALL" modified="2013-06-05T10:40:57.750Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption text</caption>
        </topicref>
      </topicref>
    </map>

    а вот, другой...

    <?xml version="1.0" encoding="UTF-8"?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="413175585366877" build="ALL" modified="2013-02-27T17:35:29.922Z" icon="0" href="xmlFilename">
        <caption translate="true">Caption Text</caption>
        <topicref type="topic" id="413205215997365" build="ALL" modified="2013-02-15T16:10:54.298Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
        <topicref type="topic" id="413177176200927" build="ALL" modified="2013-02-12T14:04:23.600Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
      <topicref type="topic" id="413232741190575" build="ALL" modified="2013-02-18T10:01:28.675Z" icon="0" href="xmlFilename">
        <caption translate="true">Caption Text</caption>
        <topicref type="topic" id="413236232967992" build="ALL" modified="2013-02-18T10:01:05.083Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
        <topicref type="topic" id="413236237162494" build="ALL" modified="2013-02-18T10:01:52.699Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
      </topicref>
      <navref href="xmlFilename::root" build="ALL" id="413245773596338" modified="2013-02-19T10:07:06.311Z" merge="compile">
        <caption translate="true">Caption Text</caption>
      </navref>
      <navref href="xmlFilename::root" build="ALL" id="413243513340855" modified="2013-02-19T10:07:50.259Z" merge="compile">
        <caption translate="true">Caption Text</caption>
      </navref>
      <navref href="xmlFilename Data::root" build="ALL" id="413246049526710" modified="2013-02-19T10:24:32.194Z" merge="compile">
        <caption translate="true">Caption Text</caption>
      </navref>
      <navref href="xmlFilename::root" build="ALL" id="414722671395938" modified="2013-07-17T11:00:09.046Z" merge="compile">
        <caption translate="true">Caption Text</caption>
      </navref>
      <navref href="xmlFilename::root" build="ALL" id="413245920912171" modified="2013-02-19T14:15:07.913Z" merge="compile">
        <caption translate="true">Caption Text</caption>
      </navref>
      <navref href="xmlFilename::root" build="ALL" id="413247021191226" modified="2013-02-19T16:06:44.871Z" merge="compile">
        <caption translate="true">Caption Text</caption>
      </navref>
     

    Вообще, это дерево документации, которая в конечном счете компилируется в CHM файл. Каждый узел topicref содержит какую-то инфу о топике...его ID, дату редактирования и собственно ссылку на реальный xml файл с контентом. Узел caption содержит заголовок топика.

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

    Во втором примере Xml встречаются узлы naveref - они означают, что в текущий проект присоединен другой проект со своим деревом...он может описывать какую-то отдельно взятую функциональность и лежать в отдельной папке...и иметь свое дерево.

    Т.е. еще раз...в этой размытой картинке, какой-либо узел - может быть отдельным проектом и подключаться в это дерево из другого места. Если такие проекты не подключаются, то структура xml файла проекта будет состоять из узлов topicref и caption если подключаются, то будет присутствовать узел navref.

    По хорошему, мне нужно, выбрать путь к самому главному проекту, загрузить его в форму, и увидеть в listview дерево + все дочерние подпроекты, которые в него входят. Имена узлов, мне вообще не нужны. В ListView нужно отображать только заголовки топиков и их структуру. Т.е то, что имеем на размытой картинке - дерево проекта. 

    Спасибо.


    2 сентября 2013 г. 5:28
  • Как я понял, ListView вообще не нужен.

    Если нужно дерево - нужно использовать TreeView.

    Подгружать поддеревья из других файлов - не проблема.

    2 сентября 2013 г. 10:13
  • А  как в этом случае атрибуты выводить?

    Дерево может быть по дефолту развернуто? Чтобы мне не приходилось разворачивать каждый нод!? 

    Подгружать поддеревья из других файлов - не проблема. Как это сделать ? :)

    Спасибо.

    2 сентября 2013 г. 10:32
  • Вы публикуете скриншот, на котором только дерево, а потом спрашиваете, как атрибуты выводить. Покажите картинку, как именно должен выглядеть желаемый интерфейс.

    Я готов помочь советом. Я готов помочь кодом. Я даже готов разработать интерфейс. Однако, это тянет уже на оплачиваемую работу, нэ?

    -----

    Допустим, имеется "file.xml":

    <?xml version="1.0" encoding="utf-8" ?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="412975879231386" build="ALL" modified="2013-04-25T14:51:50.826Z" icon="0" href="Some other text">
        <caption translate="true">Some Text_PARENT</caption>
        <topicref type="topic" id="413135726611570" build="ALL" modified="1899-12-30" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
        <topicref type="topic" id="413119294865986" build="ALL" modified="1899-12-30" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
        <topicref type="topic" id="412975691218237" build="ALL" modified="2013-01-23T15:43:26.109Z" icon="0" href="Some other text">
          <caption translate="true">Some Text_CHILD</caption>
        </topicref>
      </topicref>
    </map>


    и "root.xml":

    <?xml version="1.0" encoding="utf-8" ?>
    <map xmlns:xsi="http://www.w3.org/2001/XInclude">
      <topicref type="topic" id="413175585366877" build="ALL" modified="2013-02-27T17:35:29.922Z" icon="0" href="xmlFilename">
        <caption translate="true">Caption Text</caption>
        <topicref type="topic" id="413205215997365" build="ALL" modified="2013-02-15T16:10:54.298Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
        <topicref type="topic" id="413177176200927" build="ALL" modified="2013-02-12T14:04:23.600Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
        </topicref>
        <topicref type="topic" id="413232741190575" build="ALL" modified="2013-02-18T10:01:28.675Z" icon="0" href="xmlFilename">
          <caption translate="true">Caption Text</caption>
          <topicref type="topic" id="413236232967992" build="ALL" modified="2013-02-18T10:01:05.083Z" icon="0" href="xmlFilename">
            <caption translate="true">Caption Text</caption>
          </topicref>
          <topicref type="topic" id="413236237162494" build="ALL" modified="2013-02-18T10:01:52.699Z" icon="0" href="xmlFilename">
            <caption translate="true">Caption Text</caption>
          </topicref>
        </topicref>
        <navref href="file.xml" build="ALL" id="413245773596338" modified="2013-02-19T10:07:06.311Z" merge="compile">
          <caption translate="true">Caption Text</caption>
        </navref>
      </topicref>
    </map>


    В атрибуте href путь к файлу.

    Код для обработки:

    using System;
    using System.Linq;
    using System.Windows.Forms;
    using System.Xml.Linq;
    
    namespace WinForm_MSDN_XML
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string path = "root.xml";
                var xDocument = XDocument.Load(path);
    
                // Добавляем первую колонку
                listView1.Columns.Add("XML Content Tree");
    
                // Добавляем колонки с именами, как у атрибутов узла caption (допустимо больше одного)
                foreach (var attr in xDocument.Root.Element("topicref").Element("caption").Attributes())
                    listView1.Columns.Add(attr.Name.LocalName);
    
                // Добавляем колонки с именами, как у атрибутов элемента topicref.
                // То есть у всех таких элементов должно быть одинаковое количество одинаковых атрибутов.
                foreach (var attr in xDocument.Root.Element("topicref").Attributes())
                    listView1.Columns.Add(attr.Name.LocalName);
    
                processXml(path, 0);
    
                listView1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize);
            }
    
            void processXml(string path, int curDepth)
            {
                var xDocument = XDocument.Load(path);
                int depth = 0;
    
                foreach (var elem in xDocument.Descendants("topicref"))
                {
                    // Глубина вложенности текущего элемента topicref
                    depth = elem.Ancestors().Count() - 1;
    
                    // Отступ для красивого форматирования
                    string indent = new string(' ', (curDepth + depth) * 4);
    
                    // Значение элемента caption с отступом будет в первой колонке
                    string firstSubItem = indent + elem.Element("caption").Value;
                    var item = new ListViewItem(firstSubItem);
    
                    // Значения атрибутов элемента caption
                    var subItems = elem.Element("caption").Attributes().Select(a => a.Value).ToArray();
                    item.SubItems.AddRange(subItems);
    
                    // В остальных колонках будут значения атрибутов текущего элемента topicref
                    subItems = elem.Attributes().Select(a => a.Value).ToArray();
                    item.SubItems.AddRange(subItems);
    
                    listView1.Items.Add(item);
                }
    
                // Обрабатываем файлы, имена которых находятся в атрибуте href узлов navref
                foreach (var elem in xDocument.Descendants("navref"))
                {
                    string fileName = elem.Attribute("href").Value;
                    processXml(fileName, curDepth + depth);
                }
            }
        }
    }

    На форме только ListView.

    Атрибуты узла navref тоже можно показать (сейчас они не показываются), при желании. Однако, show me the desired GUI!

    2 сентября 2013 г. 16:25
  • Вы публикуете скриншот, на котором только дерево, а потом спрашиваете, как атрибуты выводить. Покажите картинку, как именно должен выглядеть желаемый интерфейс.

    Желаемый интерфейс, примерно такой. Его я уже публиковал. 

    Я готов помочь советом. Я готов помочь кодом. Я даже готов разработать интерфейс. Однако, это тянет уже на оплачиваемую работу, нэ?

    Возможно, Вы правы! :) Вы и так, я считаю уделяете достаточно внимания, Поэтому, буду признателен за первые 2 пункта...хватит совета..и немного кода ))) Остальное по Вашему усмотрению :) Я не программист и делаю это не в коммерческих, а в сугубо образовательных целях. За Вашу помощь, в качестве благодарности, с удовольствием проставился бы пивом :))) Но в силу того,что мы скорее всего, живем в разных странах...к сожалению не получится )

    • Помечено в качестве ответа Andrey Langovoy 14 сентября 2013 г. 7:36
    3 сентября 2013 г. 5:33
  • Задача решена?

    На мой взгляд, код в моём предыдущем сообщении выводит данные именно в требуемом виде. Причём из вложенных файлов тоже. Или что-то не устраивает?

    • Помечено в качестве ответа Andrey Langovoy 14 сентября 2013 г. 7:36
    • Снята пометка об ответе Andrey Langovoy 14 сентября 2013 г. 7:36
    6 сентября 2013 г. 10:43