Alex Rivera | Logout

How to use a LINQ query to get XElement values when XElements have same name

Asked 2009-05-20T21:19:36.663
9

I have a piece of xml like the following:

<Table>
  <Record>
    <Field>Value1_1</Field>
    <Field>Value1_2</Field>
  </Record>
  <Record>
    <Field>Value2_1</Field>
    <Field>Value2_2</Field>
  </Record>
</Table>

What i would like is a LINQ query that generates an IEnumerable that i can assign as the datasource of a DataGrid. What i have so far is as follows:

var temp = from record in table.Elements("Record")
            select record.Element("Field").Value

The fact that I can have multiple field elements is my stumbling block.

In the above example, what i need is something like an IEnumerable<string,string>. The datagrid would look something like this:

Value1_1, Value1_2
Value2_1, Value2_2
Edit
Report

3 Answers

1

I don't get what the problem is and why a number of these answers look so complicated :-/ Here is my offering:

var r = (from record in table.Elements("Record")
         select (from element in record.Elements("Field")
                 select element.Value));

// => IEnumerable<IEnumerable<string>>

The inner IEnumerable is for the columns and the outer is for the rows. (The question is kind of confusing because there is no IEnumerable<T,T'>, the above is my adaptation of the intent.)

You could make the inner IEnumerable into a string (e.g. Join on ", "), but that's not very fun to put into a grid if you mean the values as columns!

var r = (from record in table.Elements("Record")
         select String.Join(", ",
             record.Elements("Field").Select(f => f.Value).ToArray());

// => IEnumerable<string>

The above could likely be made nicer if I actually knew LINQ Expressions. However, it works and covers the "other" case -- the "ToArray" is for .NET 3.5 and below.

answered 2010-11-10T05:57:58.907
0

I may be way off in what you're looking for, but are you looking for something like this?

        DataSet ds = new DataSet("Records DS");
        ds.Tables.Add("Records");
        foreach (XElement record in table.Descendants("Record"))
        {
            var temp = from r in record.Descendants("Field")
                       select r.Value;

            string[] datum = temp.ToArray();
            if (datum != null
                && datum.Length > 0)
            {
                foreach (string s in datum)
                    ds.Tables[0].Columns.Add();
                DataRow row = ds.Tables[0].NewRow();
                row.ItemArray = datum;
                ds.Tables[0].Rows.Add(row);
            }
        }

Then return ds and set the DataMember to "Records"

answered 2009-05-21T22:01:05.607
0

Would an

IEnumerable<List<string>>

work? (not sure how to get that to display inline)

var recordList = from record in data.Elements("record") select record;
List<List<string>> x = new List<List<string>>(recordList.Count());
foreach (var record in recordList)
{
  var z = from field in record.Elements("field") select field.Value;
  x.Add(z.ToList());
}
return x.AsEnumerable();

Don't know if that works for your specific scenario or not.

answered 2009-05-21T23:00:51.150

Your Answer