Linq问题:合并条款
问题描述:
Grettings!Linq问题:合并条款
我有一些XML,看起来像这样:
<Root>
<SectionA>
<Item id="111">
<Options>
<Option val="a" cat="zzz">
<Package value="apple" />
<Feature value="avacado" />
</Option>
<Option val="b" cat="yyy">
<Package value="banana" />
<Feature value="blueberry" />
</Option>
</Options>
</Item>
<Item id="222">
<Options>
<Option val="c" cat="xxx">
<Package value="carrot" />
<Feature value="cucumber" />
</Option>
<Option val="d" cat="www">
<Package value="dairy" />
<Feature value="durom" />
</Option>
</Options>
</Item>
</SectionA>
<SectionB>
.
.
.
</SectionB>
</Root>
我想基于项目是“111”的ID属性,一个选项是“的VAL属性来获得包和特征值一个”。
我不确定从哪里开始。我可以使用where来选择ITEM节点,但我不确定如何将它与OPTION节点上的where子句结合起来。有任何想法吗?使用的SelectMany
var doc = XDocument.Parse(xml);
var items = from i in doc.Descendants("Item")
from o in i.Descendants("Option")
where i.Attribute("id").Value == "111"
&& o.Attribute("val").Value == "a"
select new {
Package = i.Descendants("Package").Attribute("value").Value,
Feature = i.Descendants("Feature").Attribute("value").Value
};
答
这对我的作品。
var doc = XDocument.Parse(s);
var items = from item in doc.Descendants("Item")
where item.Attribute("id").Value == "111"
from option in item.Descendants("Option")
where option.Attribute("val").Value == "a"
let package = option.Element("Package").Attribute("value")
let feature = option.Element("Feature").Attribute("value")
select new { Package = package.Value, Feature = feature.Value };
items.First().Feature; // = "avacado"
items.First().Package; // = "apple"
可以省略let
部分,如果你想,他们只让匿名类型更薄。
var items = from item in doc.Descendants("Item")
where item.Attribute("id").Value == "111"
from option in item.Descendants("Option")
where option.Attribute("val").Value == "a"
select new
{
Package = option.Element("Package").Attribute("value").Value,
Feature = option.Element("Feature").Attribute("value").Value
};
其实我有点像第二个。
而非查询Linq风格。
var items = doc.Descendants("Item")
.Where(item => item.Attribute("id").Value == "111")
.SelectMany(item => item.Descendants("Option"))
.Where(option => option.Attribute("val").Value == "a")
.Select(option => new
{
Package = option.Element("Package").Attribute("value").Value,
Feature = option.Element("Feature").Attribute("value").Value
});
答
替代实现是一个自下而上的方法:
var items = xdoc
.Descendants("Option")
.Where(o => (string)o.Attribute("val") == "a" && (int)o.Ancestors("Item").Single().Attribute("id") == 111)
.Select(o => new {
Package = o.Element("Package"),
Feature= o.Element("Feature")
});
+0
我得到试图获得包和功能的值时,以下几点: “不包含'Attribute'的定义。 – Bullines 2009-04-17 01:30:06
答
这里
答
这里是VB版(VB真的岩石++中XML的东西):
Module Module1
Sub Main()
Dim xml As XElement = <Root>
<SectionA>
<Item id="111">
<Options>
<Option val="a" cat="zzz">
<Package value="apple"/>
<Feature value="avacado"/>
</Option>
<Option val="b" cat="yyy">
<Package value="banana"/>
<Feature value="blueberry"/>
</Option>
</Options>
</Item>
<Item id="222">
<Options>
<Option val="c" cat="xxx">
<Package value="carrot"/>
<Feature value="cucumber"/>
</Option>
<Option val="d" cat="www">
<Package value="dairy"/>
<Feature value="durom"/>
</Option>
</Options>
</Item>
</SectionA>
<SectionB>
</SectionB>
</Root>
Dim data = From x In xml...<Option> _
Where x.Ancestors("Item")[email protected] = "111" AndAlso [email protected] = "a" _
Select Package = x.<Package>[email protected], _
Feature = x.<Feature>[email protected]
For Each item In data
Console.WriteLine("Package: {0}, Feature: {1}", item.Package, item.Feature)
Next
Stop
End Sub
End Module
+1,因为你的管道看起来效率最高 – bendewey 2009-04-17 02:28:26