C# 使用 LINQ 查询 XDocument 的最佳方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9185226/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to query XDocument with LINQ?
提问by snappymcsnap
I have an XML document that contains a series of item nodes that look like this:
我有一个 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>
and I want to LINQ it into an anonymous type like this:
我想将它 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 = ...
});
What's the best way to pull each parameter type according to the value of its 'type' attribute? Since there are many parameter elements you wind up with root.Elements("parameter")which is a collection. The best way I can think to do it is like this by method below but I feel like there must be a better way?
根据“type”属性的值提取每个参数类型的最佳方法是什么?由于有许多参数元素,您最终会得到root.Elements("parameter")它们是一个集合。我能想到的最好的方法是通过下面的方法做到这一点,但我觉得必须有更好的方法?
(from c in root.Descendants("parameter") where (string)c.Attribute("type") == "id"
select c.Value).SingleOrDefault()
采纳答案by Jon Skeet
I would use the built-in query methods in LINQ to XML instead of XPath. Your query looks fine to me, except that:
我会使用 LINQ to XML 中的内置查询方法而不是 XPath。您的查询对我来说很好,除了:
- If there are multiple items, you'd need to find the descendants of that instead; or just use
Elementif you're looking for direct descendants of the item - You may want to pull allthe values at once and convert them into a dictionary
- If you're using different data types for the contents, you might want to cast the element instead of using
.Value - You may want to create a method to return the matching
XElementfor a given type, instead of having several queries.
- 如果有多个项目,您需要找到它的后代;或者
Element如果您正在寻找该项目的直接后代,请使用 - 您可能希望一次提取所有值并将它们转换为字典
- 如果您对内容使用不同的数据类型,您可能希望强制转换元素而不是使用
.Value - 您可能希望创建一个方法来返回
XElement给定类型的匹配项,而不是进行多个查询。
Personally I don't think I'd even use a query expression for this. For example:
我个人认为我什至不会为此使用查询表达式。例如:
static XElement FindParameter(XElement element, string type)
{
return element.Elements("parameter")
.SingleOrDefault(p => (string) p.Attribute("type") == type);
}
Then:
然后:
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")
};
I suspect you'll find that's neater than any alternative using XPath, assuming I've understood what you're trying to do.
我怀疑您会发现这比使用 XPath 的任何替代方案都要简洁,假设我已经理解您要做什么。
回答by Royi Namir
use XPATH- it is very fast ( except xmlreader- but a lotof if's)
使用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 );
}
}

