0

我有一个IEnumerable<Item>where Item 有一个名为“widgets”的属性,其中包含 xml 作为字符串。xml 包含每个小部件的元素,每个小部件可以包含一个名为“foo”的可选元素。例如:

<widgets>
    <widget code="A">
        <foo>1</foo>
    </widget>
    <widget code="B" />
</widgets>

我可以将其展平IEnumerable<Item>为代表小部件的匿名类型的 IEnumerable 吗?

4

1 回答 1

1

I'm not sure if foo can be repeating element or not, but in this case it's returned as an Enumerable<String>, which is simple enough to change.

The setup (here there are two items, with the same Widgets XML):

public class Item
{
    public string Name;
    public string Widgets;
}

var xml = "<widgets>\r\n    <widget code=\"A\">\r\n        <foo>1</foo>\r\n    </widget>\r\n    <widge" +
"t code=\"B\" />\r\n</widgets>";

var item1 = new Item {Name = "I1", Widgets = xml};
var item2 = new Item {Name = "I2", Widgets = xml};
var items = new Item[] {item1, item2}.AsEnumerable();

The widget selection process:

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

That gives you 4 items (I1 A, I1 B, I2 A, I2 B) with Name (from Item) and Code and Foo (from the XML) set correctly.

If you want foo to be a single element, the change is as follows (setting FirstOrDefault basically), which will give you nulls for when foo isn't around:

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()
    };
于 2012-08-13T22:20:41.760 回答