使用LINQ查询XDocument的最佳方式是什么?

17

我有一个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>

我想将其转换为一个匿名类型,使用 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 = ...
     });

根据参数的"type"属性值,最好的方法是如何获取每个参数类型?由于有许多参数元素,您最终会得到一个集合root.Elements("parameter")。我能想到的最好的方法是下面的方法,但我觉得一定有更好的方法吧?

(from c in root.Descendants("parameter") where (string)c.Attribute("type") == "id"
select c.Value).SingleOrDefault()
2个回答

32

我会使用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);
}

那么:

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")
             };

我猜你会发现这比使用XPath的任何替代方案都更加简洁,前提是我理解了你想做什么。


是的,Jon,这似乎是一个不错的方法...我还要处理的另一个问题是有时值是空字符串,因此编写一个帮助方法来处理属性查询并在出现空字符串时优雅地处理正确类型的转换可能是最明智的选择,谢谢。 - snappymcsnap

8

使用 XPATH - 它非常快(除了xmlreader - 但是有很多条件语句)

   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 );
     }

    }

8
XPath比使用内置的LINQ方法更快吗? - snappymcsnap
3
一个不幸的问题从未得到回答! - Sharif Mamun
2
@snappymcsnap 看起来答案是 不行。可以看看微软做的这个比较:Microsoft - itsho

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接