C# 当 XElements 具有相同名称时,如何使用 LINQ 查询获取 XElement 值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/890313/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use a LINQ query to get XElement values when XElements have same name
提问by JohnC
I have a piece of xml like the following:
我有一段 xml,如下所示:
<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:
我想要的是生成 IEnumerable 的 LINQ 查询,我可以将其分配为 DataGrid 的数据源。到目前为止,我所拥有的如下:
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:
在上面的例子中,我需要的是类似IEnumerable<string,string>
. 数据网格看起来像这样:
Value1_1, Value1_2
Value2_1, Value2_2
回答by Bojan Resnik
You can chain calls to Elements()
:
您可以将调用链接到Elements()
:
var temp = from field in table.Elements("Record").Elements("Field")
select field.Value;
You can also use Descendants()
:
您还可以使用Descendants()
:
var temp = from field in table.Descendants("Field")
select field.Value;
However, this will return all <Field> elements under <Table>, even if they are not within a <Record> element.
但是,这将返回 <Table> 下的所有 <Field> 元素,即使它们不在 <Record> 元素内。
回答by Richard Morgan
Would something like this help?
这样的事情会有帮助吗?
var a = from record in table.Elements("Record")
select new
{
one = (string)record.Elements().ElementAt(0),
two = (string)record.Elements().ElementAt(1)
};
回答by dss539
It sounds like you want to denormalize the field so that it fits in 1 column in your data grid.
听起来您想对该字段进行非规范化,使其适合数据网格中的 1 列。
Does the following help?
以下有帮助吗?
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();
Disclaimer: I don't do much SQL or LINQ anymore, so this probably could be made better. Feel free to change it.
免责声明:我不再做太多的 SQL 或 LINQ,所以这可能会做得更好。随意更改它。
回答by Alexander Kahoun
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"
然后返回ds
并设置DataMember
为"Records"
回答by Pita.O
You need a 2-step processs:
您需要一个 2 步过程:
Annotate the records (in lieu of attributes) and then Enumerate the fields and pass the values into an anonymous class for binding, like so:
注释记录(代替属性),然后枚举字段并将值传递到匿名类进行绑定,如下所示:
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);
}
}
回答by BenAlabaster
Er... I think you're using the wrong LINQ paradigm for this problem. You should be using LINQ to XML which is slightly different maybe than you're expecting.
呃...我认为你对这个问题使用了错误的 LINQ 范式。您应该使用 LINQ to XML,这可能与您的预期略有不同。
Check out this link:
看看这个链接:
http://msdn.microsoft.com/en-us/library/bb308960.aspx
http://msdn.microsoft.com/en-us/library/bb308960.aspx
It explains it using a structurally similar example to the one you presented.
它使用与您提供的结构相似的示例来解释它。
回答by Jonas
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.
不知道这是否适用于您的特定场景。
回答by Maulik Patel
var detail1 = from d in ds.tbl_Looking_Fors where d.Profile_ID == id select d.Looking_For ;
var detail1 = from d in ds.tbl_Looking_Fors where d.Profile_ID == id select d.Looking_For ;
string[] datum = detail1.ToArray();
if (datum != null && datum.Length > 0)
{
foreach (var row in datum)
{
Label6.Text = datum[0]+" , "+datum[1];
}
}
回答by Maulik Patel
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.)
内部 IEnumerable 用于列,外部用于行。(这个问题有点令人困惑,因为没有IEnumerable<T,T'>
,以上是我对意图的改编。)
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!
您可以将内部 IEnumerable 变成一个字符串(例如 Join on ", "),但是如果您将值作为列,那么将其放入网格并不是很有趣!
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.
如果我真的了解 LINQ 表达式,上面的内容可能会变得更好。但是,它可以工作并涵盖“其他”情况——“ToArray”适用于 .NET 3.5 及更低版本。
回答by R.Silva
Maybe this?
也许这个?
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);
}
}