素不相识!
我有一些看起来像这样的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>
我想根据ITEM的ID属性为“111”获取PACKAGE和FEATURE值,OPTION的VAL属性为“a”。
我不知道从哪里开始。我可以使用where选择ITEM节点,但我不确定如何将它与OPTION节点上的where子句相结合。有什么想法吗?
答案 0 :(得分:7)
这适合我。
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
});
答案 1 :(得分:4)
使用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
};
答案 2 :(得分:0)
这是一种自下而上的方法:
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")
});
答案 3 :(得分:0)
这是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").@id = "111" AndAlso x.@val = "a" _
Select Package = x.<Package>.@value, _
Feature = x.<Feature>.@value
For Each item In data
Console.WriteLine("Package: {0}, Feature: {1}", item.Package, item.Feature)
Next
Stop
End Sub
End Module