我正在使用Linq解析xml文档,但我遇到的情况是我不知道如何处理这个问题。我发现/尝试过的所有东西似乎都不起作用。正如您在下面看到的(非常简单的场景)OrderAmount为空。这是一个十进制字段。当我试图在LINQ中处理它时,它一直在轰炸。我尝试过使用deimcal ?,使用null检查等,似乎没有任何工作(很可能是用户错误)。任何建议,将不胜感激。
当元素是非字符串(如小数)并且为空时如何处理?
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>();
答案 0 :(得分:4)
仅当元素实际为XElement
时,decimal?
到null
的演员才会返回null
。
我认为最可读的解决方案是这样的:
elem.IsEmpty ? null : (decimal?)elem
如果您经常使用它,您可能希望将其放入扩展方法中。或者只是在LINQ查询中使用let
,不要重复选择元素的代码。
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
}
如果您可以更改XML,另一个选项就是省略代表null
的元素。它应该与您已有的代码一起使用。
编辑:扩展方法如下所示:
static class XElementExtensions
{
public static decimal? ToNullableDecimal(this XElement elem)
{
return elem.IsEmpty ? null : (decimal?)elem;
}
}
你会像这样使用它:
OrderAmount = orders.Element("OrderAmount").ToNullableDecimal()
答案 1 :(得分:3)
怎么样
OrderAmount = String.IsNullOrEmpty(orders.Element("OrderAmount").Value) ?
default(decimal?) : Decimal.Parse(orders.Element("OrderAmount").Value),
根据svick的评论,这可能更安全
OrderAmount = String.IsNullOrEmpty(orders.Element("OrderAmount").Value) ?
default(decimal?) : (decimal)orders.Element("OrderAmount"),
答案 2 :(得分:0)
我认为你想要元素的价值而不是元素本身。
编辑:如果你真的开始保持演员表,那么这是一个通过单元测试,你可以使用它来获得一种可能更令人愉悦的格式:
private XDocument BuildDocument()
{
var myAmount = new XElement("OrderNumber", 12345);
var myNumber = new XElement("OrderAmount");
var myOrder = new XElement("Order", myAmount, myNumber);
var myOrders = new XElement("Orders", myOrder);
return new XDocument(myOrders);
}
private class Order
{
public int OrderNumber { get; set; }
public decimal? OrderAmount { get; set; }
}
[TestMethod]
public void TestMethod()
{
var myDoc = BuildDocument();
List<Order> myOrders = (from orders in myDoc.Descendants("Order")
select new Order
{
OrderNumber = (int)orders.Element("OrderNumber"),
OrderAmount = GetAmount(orders.Element("OrderAmount"))
}).ToList<Order>();
}
private static decimal? GetAmount(XElement e)
{
if (e == null || string.IsNullOrEmpty(e.Value))
{
return 0.0M;
}
return (decimal?)e;
}
(你仍然需要添加代码来处理OrderAmount的值类似于“Asdf”的情况)
答案 3 :(得分:0)
您如何在Order类中声明OrderAmount?尝试声明
public decimal? OrderAmount { get; set; }