【问题标题】:C# : select multiple nodes from XML stringC#:从 XML 字符串中选择多个节点
【发布时间】:2020-03-15 08:52:51
【问题描述】:

通过下面的代码,我试图在 DataGridView 中显示 XML 节点。第一行应包含红色和蓝色,第二行应包含绿色和黄色。

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 |

如何选择两个颜色值作为 datagridview 的结果:

结果

| red | blue |
| green | yellow |

【问题讨论】:

  • OP 中的 xml 似乎格式不正确。请验证
  • xml 看起来不正确。没有关闭color标签
  • 感谢 cmets 我已更改 xml 字符串

标签: c# xml datagridview nodes


【解决方案1】:

如果您想要显示结果的方式,则必须做更多的工作,仅使用 linq 表达式是不够的

首先。像这样更改您的链接查询:

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

我们为我们的结果类添加一个索引,以便我们稍后可以使用它来将颜色映射到他们自己的列。

接下来,您需要转换数据,否则所有颜色都将放在一列中,因为每个属性都映射到一列:

我在下面的代码中添加了一些 cmets 来解释它的作用。


// 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 |

【讨论】:

  • 非常感谢AimusSage!这正是我正在寻找的。​​span>
【解决方案2】:

首先,您的 xml 看起来格式不正确。假设这是错字,您可以使用

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

输出

【讨论】:

  • 您好 Anu,感谢您的回答,但由于某种原因,结果不会显示在 datagridview 中?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 1970-01-01
  • 2016-07-12
相关资源
最近更新 更多