0

I'm deserializing data from an XML file in order to show the data in a gridview. Here is the XML file content:

<Params>
   <Param name="Paramètre #1">
      <Value> 1.1 </Value>
      <Value> 1.2 </Value>
      <Value> 1.3 </Value>
   </Param>
   <Param name="Paramètre #2">
      <Value> 2.1 </Value>
      <Value> 2.2 </Value>
   </Param>
   <Param name="Paramètre #3">
      <Value> 3.1 </Value>
      <Value> 3.2 </Value>
      <Value> 3.3 </Value>
      <Value> 3.4 </Value>
   </Param>
</Params>

I would like the gridview to rend like this:

Expected result

All i've been able to do is this:

Actual result

Is there a way to store any value of a parameter in a column whatever the number of values of a parameter?

Here is the Markup:

<html lang="fr">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
    <form runat="server">
        <asp:Label runat="server" ID="Lb" ></asp:Label>
        <asp:GridView runat="server" ID="Gdv" AutoGenerateColumns="false">
            <Columns>
                <asp:BoundField HeaderText="Parameters" DataField="Name"></asp:BoundField>
                <asp:TemplateField HeaderText="Values">
                    <ItemTemplate>
                        <asp:Label ID="LbGrid" runat="server" Text="<%# GetValues(Container.DataItem) %>"></asp:Label>
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
    </form>
</body>
</html>

And here is the code-behind:

public partial class SiteMaster : MasterPage
{
    List<Param> Parameters { get; set; }
    protected void Page_Load(object sender, EventArgs e)
    {
        StreamReader sr = new StreamReader(@"D:\Utilisateurs\valen\Desktop\ParamsTab\XML\Main.xml");
        XmlSerializer deserializer = new XmlSerializer(typeof(List<Param>), new XmlRootAttribute("Params"));
        Parameters = (List<Param>)deserializer.Deserialize(sr);
        Gdv.DataSource = Parameters;
        Gdv.DataBind();
        sr.Close();
    }
    public string GetValues(object param)
    {
        Param parameter = (Param)param;
        string values = string.Empty;
        values += string.Join(",", parameter.Values);
        return values;
    }
}

And here is the class used as a datasource:

public class Param
{
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlElement("Value")]
    public List<string> Values { get; set; }
}
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Valentin
  • 1
  • 1

3 Answers3

0

It looks like you want one column for each value. But in your code, you only create a single column for all values.

If you don't know the number of parameters in the XML file, you have to make this dynamic. Have a look at Filling a Datagrid with dynamic Columns for how to do that.

If you never have more than 4 parameters, then the easiest solution is probably to just hard-code 4 columns like this:

<asp:GridView runat="server" ID="Gdv" AutoGenerateColumns="false" ItemType="Param">
<Columns>
    <asp:BoundField HeaderText="Parameters" DataField="Name" />
    <asp:TemplateField HeaderText="Value#1">
        <ItemTemplate><%# Item.Values?.ElementAtOrDefault(0) %></ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Value#2">
        <ItemTemplate><%# Item.Values?.ElementAtOrDefault(1) %></ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Value#3">
        <ItemTemplate><%# Item.Values?.ElementAtOrDefault(2) %></ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Value#4">
        <ItemTemplate><%# Item.Values?.ElementAtOrDefault(3) %></ItemTemplate>
    </asp:TemplateField>
</Columns>

gnud
  • 77,584
  • 5
  • 64
  • 78
0

Use xml linq. The code is completely dynamic and creates a pivot table which you can use a the binding source of your Grid.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;


namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            int maxParameters = doc.Descendants("Param").Max(x => x.Elements("Value").Count());

            DataTable dt = new DataTable();
            dt.Columns.Add("Parameters", typeof(string));
            for (int i = 1; i <= maxParameters; i++)
            {
                dt.Columns.Add("Value#" + i.ToString(), typeof(string));
            }

            foreach (XElement param in doc.Descendants("Param"))
            {
                List<string> row = new List<string>() { (string)param.Attribute("name")};
                row.AddRange(param.Elements("Value").Select(x => (string)x));
                dt.Rows.Add(row.ToArray());
            }

        }
    }
}
jdweng
  • 33,250
  • 2
  • 15
  • 20
0

First, thank you very much for the reply. All your solutions work well for a Datagrid. But not in case of a Gridview. Actually, i continued to search and i found that i just had to add ItemTemplate in the code-behind. I haven't find how to do it yet, so if you have a solution, i'd be glad to take it. Thank you all

Valentin
  • 1
  • 1