14

我正在使用现有的 XML 文档,该文档的结构(部分)如下:

<Group>
    <Entry>
        <Name> Bob </Name>
        <ID> 1 </ID>
    </Entry>
    <Entry>
        <Name> Larry </Name>
    </Entry>
</Group>

我正在使用 LINQ to XML 查询 XDocument 以检索所有这些条目,如下所示:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string)g.element("Name").Value,
        id = g.Elements("ID").Count() > 0 ? (string)g.Element("ID").Value : "none"
    };

“ID”元素并不总是存在,所以我的解决方案是上面的 Count() 爵士乐。但我想知道是否有人有更好的方法来做到这一点。我仍然对这些新东西感到满意,我怀疑可能有比我目前做的更好的方法来做到这一点。

有没有更好/更喜欢的方式来做我想做的事?

4

3 回答 3

23

XElement实际上有有趣的显式转换运算符,在这种情况下可以做正确的事情。

因此,您实际上很少需要访问该.Value属性。

这就是您的投影所需的全部内容:

var items =
    from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string) g.Element("Name"),
        id = (string) g.Element("ID") ?? "none",
    };

如果您希望ID在匿名类型中使用 的值作为整数:

var items =
    from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string) g.Element("Name"),
        id = (int?) g.Element("ID"),
    };
于 2008-11-10T16:32:20.470 回答
3

在类似的情况下,我使用了扩展方法:

    public static string OptionalElement(this XElement actionElement, string elementName)
    {
        var element = actionElement.Element(elementName);
        return (element != null) ? element.Value : null;
    }

用法:

    id = g.OptionalElement("ID") ?? "none"
于 2008-11-10T15:55:19.187 回答
1

怎么样:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry")
            let idEl = g.Element("ID")
            select new
            {
                name = (string)g.element("Name").Value,
                id = idEl == null ? "none" : idEl.Value;
            };

如果这个 barfs, then FirstOrDefault()etc 可能有用,否则只需使用扩展方法(如已经建议的那样)。

于 2008-11-10T15:57:34.517 回答