当XElements具有相同名称时,如何使用LINQ查询来获取XElement值

时间:2009-05-20 21:19:37

标签: c# linq-to-xml

我有一块xml如下:

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

我想要的是一个LINQ查询,它生成一个IEnumerable,我可以将其指定为DataGrid的数据源。我到目前为止的内容如下:

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

我可以拥有多个场元素的事实是我的绊脚石。

在上面的例子中,我需要的是IEnumerable<string,string>。 数据网格看起来像这样:

Value1_1, Value1_2
Value2_1, Value2_2

10 个答案:

答案 0 :(得分:10)

这样的事情有帮助吗?

var a = from record in table.Elements("Record")
    select new
    {
        one = (string)record.Elements().ElementAt(0),
        two = (string)record.Elements().ElementAt(1)
    };

答案 1 :(得分:3)

听起来你想要对字段进行非规范化,使其适合数据网格中的1列。

以下是否有帮助?

var table = XElement.Parse(@"<Table>
                                <Record><Field>Value1_1</Field><Field>Value1_2</Field></Record>
                                <Record><Field>Value2_1</Field><Field>Value2_2</Field></Record>
                             </Table>");


var temp = from record in table.Elements("Record")
           from field in record.Elements("Field")
           group field.Value by record into groupedFields
           select groupedFields.Aggregate((l, r) => l + ", " + r);

foreach (var row in temp)
    Console.WriteLine(row);

Console.ReadKey();

免责声明:我不再做很多SQL或LINQ,所以这可能会更好。随意改变它。

答案 2 :(得分:1)

我不知道问题是什么以及为什么这些答案看起来如此复杂: - /这是我的产品:

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

// => IEnumerable<IEnumerable<string>>

内部IEnumerable用于列,外部用于行。 (问题有点令人困惑,因为没有IEnumerable<T,T'>,上面是我对意图的改编。)

你可以将内部IEnumerable变成一个字符串(例如Join on“,”),但如果你把这些值表示为列,那么放入网格并不是很有趣!

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

// => IEnumerable<string>

如果我真的知道LINQ表达式,上面的内容可能会更好。但是,它可以工作并涵盖“其他”案例 - “ToArray”适用于.NET 3.5及更低版本。

答案 3 :(得分:1)

也许这个?

using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;
using System.Diagnostics;

[TestMethod]
    public void Linq_XElement_Test()
    {


    string xml = @"<Table>
  <Record>
    <Field>Value1_1</Field>
    <Field>Value1_2</Field>
  </Record>
  <Record>
    <Field>Value2_1</Field>
    <Field>Value2_2</Field>
  </Record>
</Table>";

    XElement elements = XElement.Parse(xml);

    var qryRecords = from record in elements.Elements("Record")
                  select record;

    foreach (var rec in qryRecords)
    {
        Debug.WriteLine(rec.Value);
    }

    var qryFields = from record in elements.Elements("Record")
                 from fields in record.Elements("Field")
                 select fields;

    foreach (var fil in qryFields)
    {
        Debug.WriteLine(fil.Value);
    }

    IEnumerable<string> list = qryFields.Select(x => x.Value);

    foreach (string item in list)
    {
        Debug.WriteLine(item);
    }


}

答案 4 :(得分:0)

您可以将来电链接到Elements()

var temp = from field in table.Elements("Record").Elements("Field")
           select field.Value;

您还可以使用Descendants()

 var temp = from field in table.Descendants("Field")
            select field.Value;

然而,这将返回所有&lt; Field&gt; &lt; Table&gt;下的元素,即使它们不在&lt; Record&gt;范围内元件。

答案 5 :(得分:0)

我可能想要找你想要的东西,但是你在找这样的东西吗?

        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);
            }
        }

然后返回ds并将DataMember设置为"Records"

答案 6 :(得分:0)

您需要两个步骤:

注释记录(代替属性)然后 枚举字段并将值传递给匿名类进行绑定,如下所示:

string xml = [string-goes-here];

  XElement elem = XElement.Parse(xml);

  int count= 0;
  foreach(XElement recordElems in elem.Elements("Record")){
    recordElems.SetAttributeValue("id", count);
    count++;
  }
  var temp = from record in elem.Elements("Record")
             from field in record.Elements("Field")
             select new { Record = "Record " + record.Attribute("id").Value, Field = field.Value };

  foreach (var item in temp)
  {
    Console.WriteLine("{0}: {1}", item.Record, item.Field);
  }
}

答案 7 :(得分:0)

呃......我认为你正在使用错误的LINQ范例来解决这个问题。您应该使用LINQ to XML,这可能与您期望的略有不同。

点击此链接:

http://msdn.microsoft.com/en-us/library/bb308960.aspx

它使用与您所呈现的结构相似的结构来解释它。

答案 8 :(得分:0)

会不会

IEnumerable<List<string>>

工作? (不知道如何让它显示内联)

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();

不知道这是否适用于您的具体情况。

答案 9 :(得分:0)

var detail1 =来自ds.tbl_Looking_Fors中的d                              其中d.Profile_ID == id                              选择d.Looking_For;

            string[] datum = detail1.ToArray();
            if (datum != null && datum.Length > 0)
            {
                foreach (var row in datum)
                {
                    Label6.Text = datum[0]+" , "+datum[1];
                }

            }