使用LINQ查询XDocument的最佳方法?

sna*_*nap 16 c# xml linq

我有一个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的任何替代方案更整洁,假设我已经理解你正在尝试做什么.


Roy*_*mir 7

使用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)

  • 那么xpath比使用内置的LINQ方法更快吗? (8认同)
  • 一个永远无法回答的不吉利的问题! (3认同)
  • @snappymcsnap 似乎答案是**不**。请参阅 [Microsoft](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/comparison-of-xpath-and-linq-to-xml#performance -差异) (2认同)