WinForms, DataGridView: фильтрация данных XML с использованием атрибутов из нескольких узлов - PullRequest
0 голосов
/ 15 декабря 2010

У меня есть файл данных XML в формате, похожем на этот:

<?xml version="1.0" standalone="yes"?>
<Root>
  <FirstLevel Id="1">
    <SecondLevel Id="1">
      <ThirdLevel Id="1">
        <DataElement Id="1" Data="hello" />
        <DataElement Id="2" Data="world" />
      </ThirdLevel>
      <ThirdLevel Id="2">
        <DataElement Id="1" Data="blablabla" />
        <DataElement Id="2" Data="blablabla" />
      </ThirdLevel>    
    </SecondLevel>
    <SecondLevel Id="2">
      <ThirdLevel Id="1">
        <DataElement Id="1" Data="asdf" />
        <DataElement Id="2" Data="qwerty" />
      </ThirdLevel>
      <ThirdLevel Id="2">
        <DataElement Id="1" Data="gggggg" />
        <DataElement Id="2" Data="dddddd" />
      </ThirdLevel>    
    </SecondLevel>
  </FirstLevel>
</Root>

И я пытаюсь создать приложение WinForms, используя DataGridView, который связывается с этим файлом XML.И отображает следующее в сетке, в зависимости от выбранных параметров навигации.Например, если пользователь выбирает навигацию по FirstLevel, SecondLevel и ThirdLevel с идентификатором 1 для всех, должны отображаться только следующие 2 строки с возможностью записи любых изменений в XML:

Id   Data
----------
1    hello
2    world

Такдалеко, я могу получить только все строки (таблицы данных) для отображения:

Id  Data
---------
1   hello
2   world
1   blablabla
2   blablabla
1   asdf
2   qwerty
... etc

Используя следующий код:

DataSet dataSet = new DataSet();
dataSet.ReadXML("Data.xml");
DataView dataView = new DataView(dataSet.Tables["DataElement"]);
BindingSource source = new BindingSource();
source.DataSource = dataView;
dataGridView1.DataSource = source;

Как я могу отфильтровать мои данные так, чтобы только 2 строкиотображается, как описано выше?Спасибо!

ОБНОВЛЕНИЕ:

Спасибо, Конрад, за вашу помощь!Тем не менее, я все еще пытаюсь понять, как «перемещаться» между этими тремя уровнями, так как добавление DataMember не совсем добавляет фильтрацию.Таким образом, чтобы иметь возможность, скажем, отображать данные для критериев FirstLevel Id = 2, SecondLevel Id = 1, ThirdLevel Id = 5 (или чего-то еще), мне нужно было бы добавить все три к:

DataView dataView = new DataView(dataSet.Tables["FirstLevel_SecondLevel_ThirdLevel"]);

А затем добавьте RowFilter с чем-то вроде:

dataView.RowFilter = "Id = '2'";

(а как насчет других уровней здесь?)

А затем измените DataMember следующим образом:

source.DataMember = "FirstLevel_SecondLevel_ThirdLevel_DataElement";

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

Ответы [ 3 ]

0 голосов
/ 15 декабря 2010

UPDATE Нет отношения «FirstLevel_SecondLevel_ThirdLevel», поэтому это не работает. Вы можете узнать, какие существуют, изучив коллекцию DataSet.Relations.

Когда у вас есть несколько уровней, вам нужно создать представление для каждого уровня.

        DataView firstDataView = new DataView(dataSet.Tables["FirstLevel"]);
        firstDataView.RowFilter = "Id = 1";


        DataView secondDataView  = firstDataView[0].CreateChildView("FirstLevel_SecondLevel");
        secondDataView.RowFilter = "Id = 2";

        DataView thirdDataView = secondDataView[0].CreateChildView("SecondLevel_ThirdLevel");
        DataView dataElement = thirdDataView[0].CreateChildView("ThirdLevel_DataElement");



        BindingSource source = new BindingSource();

        source.DataSource = dataElement;

        dataGridView1.DataSource = source;
0 голосов
/ 12 мая 2016

Вы можете фильтровать данные в предложении where, передавая фактическое имя элемента и выбирая точные данные после его фильтрации.

var data = (из d в XDocument.Load (_pathXML) .Descendants ("ThirdLevel"), где d.Attribute ("Id"). Значение == 1 выберите d;

Теперь вы можете отобразить данные

          if (_appNme.Any())
          {
              foreach (var item in data)
              {
                  MessageBox.Show(_appNme.Elements("Id").Single().Value);
                  MessageBox.Show(_appNme.Elements("Data").Single().Value);
              }

          }
0 голосов
/ 15 декабря 2010

Попробуйте XPath и Linq to XML.Предполагая, что XML находится в строке со знаком XML:

           var doc = XDocument.Parse(xml);
            var firstLevel = "1";
            var secondLevel = "1";
            var thirdLevel = "1";
            var query = string.Format("/Root/FirstLevel[@Id={0}]/SecondLevel[@Id={1}]/ThirdLevel[@Id={2}]/DataElement", firstLevel, secondLevel, thirdLevel);
            var results = (from i in doc.XPathSelectElements(query)
                           select new { Id = i.Attribute("Id").Value, Data = i.Attribute("Data").Value }).ToList();
            foreach (var item in results)
            {
                Console.WriteLine("{0} - {1}", item.Id, item.Data);
            }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...