>我有一个IEnumerable<Item>
,其中 Item 有一个名为"widgets"的属性,其中包含 xml 作为字符串。XML 包含每个小部件的元素,每个小部件可以包含一个名为"foo"的可选元素。例如:
<widgets>
<widget code="A">
<foo>1</foo>
</widget>
<widget code="B" />
</widgets>
我可以将IEnumerable<Item>
展平为表示小部件的匿名类型的 IEnumerable 吗?
>我不确定foo
是否可以重复元素,但在这种情况下,它作为Enumerable<String>
返回,这很简单,可以更改。
设置(这里有两个项目,具有相同的 XML Widgets
):
public class Item
{
public string Name;
public string Widgets;
}
var xml = "<widgets>rn <widget code="A">rn <foo>1</foo>rn </widget>rn <widge" +
"t code="B" />rn</widgets>";
var item1 = new Item {Name = "I1", Widgets = xml};
var item2 = new Item {Name = "I2", Widgets = xml};
var items = new Item[] {item1, item2}.AsEnumerable();
小部件选择过程:
var widgets =
from item in items
from widget in XElement.Parse(item.Widgets).Elements("widget")
select new {
Name = item.Name,
Code = widget.Attribute("code").Value,
Foo = widget.Elements("foo").Select(f => f.Value)
};
这为您提供了 4 个项目(I1 A、I1 B、I2 A、I2 B),其名称(来自项目)和代码和 Foo(来自 XML)设置正确。
如果您希望foo
成为单个元素,则更改如下(基本上FirstOrDefault
设置),这将在foo
不在时为您提供空值:
var widgets =
from item in items
from widget in XElement.Parse(item.Widgets).Elements("widget")
select new {
Name = item.Name,
Code = widget.Attribute("code").Value,
Foo = widget.Elements("foo").Select(f => f.Value).FirstOrDefault()
};