Заполнить сетку данных из XML-файла - PullRequest
0 голосов
/ 02 июля 2018

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

Я хотел бы добавить атрибуты определенного идентификатора объекта в сетку данных. К сожалению, разработанная мной процедура добавляет все атрибуты в сетку данных, а не только атрибуты выбранного объекта.

У меня следующая структура файла xml:

<?xml version="1.0" encoding="UTF-8"?>
<project>
  <configuration>
    <general>
      <verbose>True</verbose>
    </general>
    <architecture>
      <site reference="Demo Site Reference" type="WTP" id="0001" />
      <rtu dnp="77" ip="10.10.10.77" type="Schneider Electric SCADAPack 442" />
      <radio ip="10.10.10.76" />
      <hmi ip="10.10.10.75" />
    </architecture>
  </configuration>
  <database>
    <object id="0" name="object 0" description="Entry Description 0" date="22.06.2018 00:00:00" archestra="Export">
      <attributes>
        <attribute id="0" name="Attribute 0" description="Attribute 0 Description" note="Attribute 0 Note" />
        <attribute id="1" name="Attribute 1" description="Attribute 1 Description" note="Attribute 1 Note" />
      </attributes>
    </object>
    <object id="1" name="object 1" description="Entry Description 1" date="22.06.2018 00:00:00" archestra="Export">
      <attributes>
        <attribute id="0" name="Attribute 0" description="Attribute 0 Description" note="Attribute 0 Note" />
        <attribute id="1" name="Attribute 1" description="Attribute 1 Description" note="Attribute 1 Note" />
        <attribute id="2" name="Attribute 2" description="Attribute 2 Description" note="Attribute 2 Note" />
        <attribute id="3" name="Attribute 3" description="Attribute 3 Description" note="Attribute 3 Note" />
      </attributes>
    </object>
    <object id="2" name="object 2" description="Entry Description 2" date="22.06.2018 00:00:00" archestra="Export">
      <attributes>
        <attribute id="0" name="Attribute 0" description="Attribute 0 Description" note="Attribute 0 Note" />
        <attribute id="1" name="Attribute 1" description="Attribute 1 Description" note="Attribute 1 Note" />
        <attribute id="2" name="Attribute 2" description="Attribute 2 Description" note="Attribute 2 Note" />
      </attributes>
    </object>
  </database>
</project>

Следующая процедура добавляет все атрибуты:

    public static DataTable PopulateGrid(string file, string id)
    {
        //DataTable that will hold the found results
        DataTable results = new DataTable("SearchResults");
        //DataRow (used later)
        DataRow row = null;

        results.Columns.Add("id", typeof(string));
        results.Columns.Add("name", typeof(string));
        results.Columns.Add("description", typeof(string));

        XmlDocument xmldocument = new XmlDocument();
        xmldocument.Load(file);

        //** Change This **
        string query = "/project/database/object";
        string query2 = "/project/database/object/attributes/attribute";

        //now we loop through the list
        foreach (XmlNode xmlnode in xmldocument.SelectNodes(query))
        {
            if (xmlnode.Attributes["id"].Value == id)
            {
                foreach (XmlNode xmlnode2 in xmldocument.SelectNodes(query2))
                {
                    row = results.NewRow();

                    row[0] = xmlnode2.Attributes["id"].Value;
                    row[1] = xmlnode2.Attributes["name"].Value;
                    row[2] = xmlnode2.Attributes["description"].Value;

                    results.Rows.Add(row);
                }
            }
        }

        //now return the DataTable
        return results;
    }

Любая помощь для решения этой проблемы будет принята с благодарностью.

С уважением

Ответы [ 3 ]

0 голосов
/ 02 июля 2018

Я думаю, было бы намного проще, если бы вы использовали Linq To XML. то есть:

public static IEnumerable<MyData> PopulateGrid(string file, string id)
{
    var xml = XElement.Load(file);
    var result = xml.Element("database").Elements("object")
    .SelectMany(o => o.Element("attributes").Elements("attribute"))
    .Where(x => (string)x.Attribute("id") == id)
    .Select(a => new MyData
    {
        Id = (string)a.Attribute("id"),
        Name = (string)a.Attribute("name"),
        Description = (string)a.Attribute("description")
    });

    return result;
}

public class MyData
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}
0 голосов
/ 02 июля 2018

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

string query2 = "./attributes/attribute"; // path from current node


// use xmlnode instead of xmldocument
foreach (XmlNode xmlnode2 in xmlnode.SelectNodes(query2))
0 голосов
/ 02 июля 2018

В вашем втором цикле for вы звоните

xmldocument.SelectNodes(query2)

, который выбирает все узлы в документе, которые соответствуют запросу 2.

Вы можете изменить свой код на:

        string query = "/project/database/object['" + id + "']";
        string query2 = "attributes/attribute";

        var obj = xmldocument.SelectSingleNode(query);

        foreach (XmlNode xmlnode2 in obj.SelectNodes(query2))
        {
            row = results.NewRow();

            row[0] = xmlnode2.Attributes["id"].Value;
            row[1] = xmlnode2.Attributes["name"].Value;
            row[2] = xmlnode2.Attributes["description"].Value;

            results.Rows.Add(row);
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...