我有一个XML文档,其中包含一系列项目节点,如下所示:
<data>
<item>
<label>XYZ</label>
<description>lorem ipsum</description>
<parameter type="id">123</parameter>
<parameter type="name">Adam Savage</parameter>
<parameter type="zip">90210</parameter>
</item>
</data>
Run Code Online (Sandbox Code Playgroud)
我想将它LINQ成一个匿名类型,如下所示:
var mydata =
(from root in document.Root.Elements("item")
select new {
label = (string)root.Element("label"),
description = (string)root.Element("description"),
id = ...,
name = ...,
zip = ...
});
Run Code Online (Sandbox Code Playgroud)
根据"类型"属性的值拉取每个参数类型的最佳方法是什么?由于有很多参数元素,你root.Elements("parameter")
最终会收集它们.我能想到的最好的方法是通过下面的方法,但我觉得必须有更好的方法吗?
(from c in root.Descendants("parameter") where (string)c.Attribute("type") == "id"
select c.Value).SingleOrDefault()
Run Code Online (Sandbox Code Playgroud)
Jon*_*eet 28
我会使用LINQ to XML中的内置查询方法而不是XPath.您的查询对我来说很好,除了:
Element
在寻找物品的直接后代时使用.Value
XElement
给定类型的匹配,而不是具有多个查询.我个人认为我甚至不会使用查询表达式.例如:
static XElement FindParameter(XElement element, string type)
{
return element.Elements("parameter")
.SingleOrDefault(p => (string) p.Attribute("type") == type);
}
Run Code Online (Sandbox Code Playgroud)
然后:
var mydata = from item in document.Root.Elements("item")
select new {
Label = (string) item.Element("label"),
Description = (string) item.Element("description"),
Id = (int) FindParameter(item, "id"),
Name = (string) FindParameter(item, "name"),
Zip = (string) FindParameter(item, "zip")
};
Run Code Online (Sandbox Code Playgroud)
我怀疑你会发现它比使用XPath的任何替代方案更整洁,假设我已经理解你正在尝试做什么.
使用XPATH - 它非常快(除了xmlreader
- 但很多 if)
using (var stream = new StringReader(xml))
{
XDocument xmlFile = XDocument.Load(stream);
var query = (IEnumerable)xmlFile.XPathEvaluate("/data/item/parameter[@type='id']");
foreach (var x in query.Cast<XElement>())
{
Console.WriteLine( x.Value );
}
}
Run Code Online (Sandbox Code Playgroud)