You can cast the attribute to a string. If it is absent you will get null and subsequent code should check for null, otherwise it will return the value directly.
Try this instead:
var books = from book in booksXml.Descendants("book")
select new
{
Name = (string)book.Attribute("name"),
Price = (string)book.Attribute("price"),
Special = (string)book.Attribute("special")
};