如何使用C#LinqtoXML将属性值XML转换为列/值

时间:2012-09-08 03:59:01

标签: c# linq-to-xml dynamic-columns

我有一个XML文档如下:

<Registrations>
  <RegistrationForm>
    <RegValue Id="Passport" v="13.999.567" />
    <RegValue Id="FavoriteColor" v="Blue" />
    <RegValue Id="Gender" v="Male" />
  </RegistrationForm>
  <RegistrationForm>
    <RegValue Id="Passport" v="12.566.342" />
    <RegValue Id="FavoriteColor" v="Red" />
    <RegValue Id="Gender" v="Female" />
  </RegistrationForm>
</Registrations>

目标是生成一个GridView,其中不同的ID值作为列,每行包含该ID的值:

PASSPORT   | FavoriteColor | Gender
13.999.567 | Blue          | Male
12.566.342 | Red           | Female

这里的复杂性是我们可以拥有更多RegValue元素,这些元素具有我事先不知道的ID。所以应该动态生成列。例如,我可以向XML添加一个元素:<RegValue Id="Pet" v="Dog" />所以表格上应该有一个新的“Pet”列。

我开始使用C#LINQ to XML,但我只能使用硬编码列名执行查询。

2 个答案:

答案 0 :(得分:1)

通过LINQ使用XML到DataTable,您可以在GridView中显示XML。以下示例希望可以帮助您解决问题。

public void ParseXMLToDataTable()
    {
        XElement document = XElement.Parse(
       @"
            <Registrations>
              <RegistrationForm>
                <RegValue Id=""Passport"" v=""13.999.567"" />
                <RegValue Id=""FavoriteColor"" v=""Blue"" />
                <RegValue Id=""Gender"" v=""Male"" />
              </RegistrationForm>
              <RegistrationForm>
                <RegValue Id=""Passport"" v=""12.566.342"" />
                <RegValue Id=""FavoriteColor"" v=""Red"" />
                <RegValue Id=""Gender"" v=""Female"" />
              </RegistrationForm>
            </Registrations>
        ");

        List<XElement> RegistrationForm = document.Elements("RegistrationForm").ToList();

        if (RegistrationForm.Count > 0)
        {
           DataTable oGridViewTable =  XElementToDataTable(RegistrationForm);
        }
    }




public DataTable XElementToDataTable(List<XElement> oRegistrationFormList)
    {
        DataTable dt = new DataTable();

        // Generate DataTable Column
        XElement oFirstElement = oRegistrationFormList.First();

        dt.Columns.AddRange(oFirstElement.Descendants().Select(o =>
           new DataColumn(o.Attribute("Id").Value)).ToArray());


        //Generate DataTable Rows
        foreach (XElement oRegistrationForm in oRegistrationFormList)
        {
            DataRow dr = dt.NewRow();
            foreach (XElement oRegValue in oRegistrationForm.Descendants())
                dr[oRegValue.Attribute("Id").Value] = oRegValue.Attribute("v").Value; 
            dt.Rows.Add(dr);
        }

        return dt;
    }

答案 1 :(得分:0)

在我看来,你应该像你的问题那样定制。像这样:

using System.Data;
using System.Xml.Linq;
using System.Linq;

class Program
{

    public static void Main()
    {
        XDocument document = XDocument.Parse(
            @"
                <Registrations>
                  <RegistrationForm>
                    <RegValue Id=""Passport"" v=""13.999.567"" />
                    <RegValue Id=""FavoriteColor"" v=""Blue"" />
                    <RegValue Id=""Gender"" v=""Male"" />
                  </RegistrationForm>
                  <RegistrationForm>
                    <RegValue Id=""Passport"" v=""12.566.342"" />
                    <RegValue Id=""FavoriteColor"" v=""Red"" />
                    <RegValue Id=""Gender"" v=""Female"" />
                  </RegistrationForm>
                </Registrations>
            "
        );

        DataTable table = new DataTable();

        XElement firstElement = document
                                .Root
                                .Elements(
                                    "Registrations"
                                )
                                .Elements(
                                    "RegistrationForm"
                                )
                                .FirstOrDefault();


        if (firstElement == null)

            return;

        table
        .Columns
        .AddRange(
            firstElement
            .Elements(
                "RegValue"
            )
            .Select(
                e =>
                new DataColumn(e.Attribute("Id").Value)
            )
            .ToArray()
        );

        table
        .Rows
        .Add(
            document
            .Root
            .Elements(
                "Registrations"
            )
            .Elements(
                "RegistrationForm"
            )
            .Select(
                e =>
                e
                .Elements()
                .Select(
                    regValue =>
                    regValue
                    .Attribute("v")
                    .Value
                )
                .ToArray()
            )
        );

        //YOUR TABLE IS READY HERE.
    }
}