C#: выбрать несколько узлов из строки XML - PullRequest
0 голосов
/ 15 марта 2020

С помощью приведенного ниже кода я пытаюсь показать XML узлов в DataGridView. Первая строка должна содержать красный и синий, вторая строка должна содержать зеленый и желтый.

string xml = "<?xml version="1.0" encoding="utf-8"?>
<colors>
<color type="string">red</color>
<color type="string">blue</color>
</colors>
<colors>
<color type="string">green</color>
<color type="string">yellow</color>
</colors>
";

StringReader reader = new StringReader(xml);
XDocument doc = XDocument.Load(reader);

var res = doc.Descendants("colors").Select(n => new { n.Element("color").Value }).ToList());

dataGridView.DataSource = res;

Показывает только первое значение:

| red |
| green |

Как выбрать оба значения цвета в результате для обзора данных:

Результат

| red | blue |
| green | yellow |

Ответы [ 2 ]

0 голосов
/ 15 марта 2020

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

Сначала. измените запрос ссылки следующим образом:

var result = doc.Descendants("colors")
                .SelectMany((x) => x.Elements("color").Select((c, i) => new { Id = i, Color = c.Value }));

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

Далее вам понадобится чтобы преобразовать ваши данные, в противном случае все цвета будут go в одном столбце, так как каждое свойство отображается в столбец:

Я добавил несколько комментариев в приведенном ниже коде, который объясняет, что он делает.


// create a new DataTable for mapping the transformed data
var table = new DataTable();

// loop through all items to create a column for each index.
foreach (var item in result)
{
    var colName = item.Id.ToString();
    if (!table.Columns.Contains(colName))
    {
        table.Columns.Add(colName);
    }
}

// loop again through the results to add each item to the right position in the datatable
foreach (var item in result)
{
    var isMapped = false;

// a second foreach to check if it should go into an existing row
    foreach (DataRow dataRow in table.Rows)
    {
        if (dataRow[item.Id.ToString()].ToString() == "")
        {
            dataRow[item.Id.ToString()] = item.Color;
            isMapped = true; // set to true so we don't map it again later
            break; // no need to continue the loop, we found where the color belongs
        }
    }
    if (!isMapped)
    {
        var row = table.NewRow(); // it doesn't belong in an existing row
        row[item.Id.ToString()] = item.Color;
        table.Rows.Add(row);
    }
}

// Assign the new table to your view
dataGridView1.DataSource = table;

Это должно сделать это. Имейте в виду, что для больших наборов данных эти циклы могут стать медленными. Возможно, существует более оптимальное решение, но оно выполнено, и теперь у вас должны быть данные, которые выглядят следующим образом:

| red | blue |
| green | yellow |
0 голосов
/ 15 марта 2020

Начнем с того, что ваш xml не выглядит хорошо сформированным. Предполагая, что это опечатка, вы можете использовать

var result = doc.Descendants("colors")
                .Select(x=>x.Elements("color").Select(c=>c.Value));

Выход

enter image description here

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