【问题标题】:LINQ to XML optional element queryLINQ to XML 可选元素查询
【发布时间】:2008-11-10 15:50:29
【问题描述】:

我正在处理一个现有的 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() 爵士乐。但我想知道是否有人有更好的方法来做到这一点。我仍然对这些新东西感到满意,我怀疑可能有比我目前做的更好的方法来做到这一点。

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

【问题讨论】:

    标签: c# linq linq-to-xml anonymous-types


    【解决方案1】:

    XElement 实际上有 interesting explicit conversion operators 在这种情况下做正确的事情。

    因此,您实际上很少需要访问 .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"),
        };
    

    【讨论】:

    【解决方案2】:

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

        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"
    

    【讨论】:

    • ValueOrDefault(this XElement actionElement, string elementName, string defaultValue) 会更整洁。
    • 实际上完全没有必要。显式字符串转换运算符已经这样做了:msdn.microsoft.com/en-us/library/bb155263.aspx
    【解决方案3】:

    怎么样:

    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,那么 FirstOrDefault() 等可能有用,否则只需使用扩展方法(如前所述)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多