tags:

views:

137

answers:

1

The following code works but only as long as each element of the XML has an "Id" attribute.

However, if an element does not have an id attribute, LINQ throws an NullReferenceException.

How do I specify that if there is no Id attribute, just assign a null or blank?

using System;
using System.Linq;
using System.Xml.Linq;

namespace TestXmlElement2834
{
    class Program
    {
        static void Main(string[] args)
        {

            XElement content = new XElement("content",
                new XElement("item", new XAttribute("id", "4")),
                new XElement("item", new XAttribute("idCode", "firstForm"))
                );

            var contentItems = from contentItem in content.Descendants("item")
                               select new ContentItem
                               {
                                   Id = contentItem.Attribute("id").Value

                               };

            foreach (var contentItem in contentItems)
            {
                Console.WriteLine(contentItem.Id);
            }

            Console.ReadLine();


        }
    }

    class ContentItem
    {
        public string Id { get; set; }
        public string IdCode { get; set; }
    }
}
+7  A: 

(2nd edit)

Ooh - found an easier way ;-p

    from contentItem in content.Descendants("item")
    select new ContentItem
    {
        Id = (string)contentItem.Attribute("id")
    };

This works thanks to the flexible static conversion operators on XAttribute etc.


(original)

    from contentItem in content.Descendants("item")
    let idAttrib = contentItem.Attribute("id")
    select new ContentItem
    {
        Id = idAttrib == null ? "" : idAttrib.Value
    };


(1st edit)

Or add an extension method:

static string AttributeValue(this XElement element, XName name)
{
    var attrib = element.Attribute(name);
    return attrib == null ? null : attrib.Value;
}

and use:

    from contentItem in content.Descendants("item")
    select new ContentItem
    {
        Id = contentItem.AttributeValue("id")
    };
Marc Gravell
+1 Very nice :)
Andrew Hare
yes, nice, I had tried the tertiary operator but without the "let" it didn't work, thanks
Edward Tanguay
will remember that (string) casting works, excellent
Edward Tanguay