Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linq to Xml - Empty Element

Tags:

c#

linq-to-xml

I am parsing an xml doc with Linq, but i am running into a scenario where I am not sure how to handle the processing. Everything I have found / tried doesn't seem to work. As you can see below (very simple scenario) where the OrderAmount is empty. This is a decimal field. When I try to handle this in LINQ it keeps bombing. I have tried using deimcal?, using the null check, etc nothing seems to be working (Most likely user error). Any suggestions would be appreciated.

How do you handle when an element is a non string (like a decimal) and is empty ?

Xml:

<Orders>
  <Order>
    <OrderNumber>12345</OrderNumber>
    <OrderAmount/>
  </Order>
</Orders>

LINQ:

List<Order> myOrders = from orders in xdoc.Descendants("Order")
                       select new Order{
                       OrderNumber = (int)orders.Element("OrderNumber"),
                       OrderAmount = (decimal?)orders.Element("OrderAmount"),


}.ToList<Order>();
like image 669
scarpacci Avatar asked Sep 11 '25 23:09

scarpacci


1 Answers

The cast of XElement to decimal? returns null only when the element is actually null.

I think the most readable solution is something like this:

elem.IsEmpty ? null : (decimal?)elem

You might want to put this into an extension method, if you use it often. Or just use let in your LINQ query to not repeat the code that selects the element.

from orders in xdoc.Descendants("Order")
let amountElem = orders.Element("OrderAmount")
select new Order
{
    OrderNumber = (int)orders.Element("OrderNumber"),
    OrderAmount = amountElem.IsEmpty ? null : (decimal?)amountElem
}

Another option, if you can change the XML, is simply omitting the element to represent null. It should work well with the code you already have.

EDIT: The extension method would look something like this:

static class XElementExtensions
{
    public static decimal? ToNullableDecimal(this XElement elem)
    {
        return elem.IsEmpty ? null : (decimal?)elem;
    }
}

And you would use it like this:

OrderAmount = orders.Element("OrderAmount").ToNullableDecimal()
like image 170
svick Avatar answered Sep 14 '25 13:09

svick