Linq to xml选择新的PurchaseOrder

时间:2012-11-01 06:35:28

标签: linq linq-to-xml

我正试图让我的脑袋“Linq to xml”,所以让我跳到它。我有这个xml:

<?xml version="1.0"?>
<PurchaseOrders>
  <PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
    <Address Type="Shipping">
      <Name>Ellen Adams</Name>
      <Street>123 Maple Street</Street>
      <City>Mill Valley</City>
      <State>CA</State>
      <Zip>10999</Zip>
      <Country>USA</Country>
    </Address>
    <Address Type="Billing">
      <Name>Tai Yee</Name>
      <Street>8 Oak Avenue</Street>
      <City>Old Town</City>
      <State>PA</State>
      <Zip>95819</Zip>
      <Country>USA</Country>
    </Address>
    <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
    <Items>
      <Item PartNumber="872-AA">
        <ProductName>Lawnmower</ProductName>
        <Quantity>1</Quantity>
        <USPrice>148.95</USPrice>
        <Comment>Confirm this is electric</Comment>
      </Item>
      <Item PartNumber="926-AA">
        <ProductName>Baby Monitor</ProductName>
        <Quantity>2</Quantity>
        <USPrice>39.98</USPrice>
        <ShipDate>1999-05-21</ShipDate>
      </Item>
    </Items>
  </PurchaseOrder>
</PurchaseOrders>

然后我创建了som简单对象:

public class PurchaseOrder
{
    public string PurchaseOrderNumber { get; set; }
    public string OrderDate { get; set; }
    public Address BillingAddress { get; set; }
    public Address ShippingAddress { get; set; }
    public string DeliveryNotes { get; set; }
    public List<Item> Items { get; set; }
}

public class Address
{
    public string Type { get; set; }
    public string Name  { get; set; }
    public string Street { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }
}

public class Item
{
    public string PartNumber { get; set; }
    public string ProductName { get; set; }
    public string Quantity { get; set; }
    public string USPrice { get; set; }
    public string Comment { get; set; }
}

然后我继续做我的linq:

    var orders = (from order in XDocument.Load(Server.MapPath("/App_Data/Order.xml")).Descendants("PurchaseOrder")
select new PurchaseOrder
{
    PurchaseOrderNumber = order.Attribute("PurchaseOrderNumber").Value,
    OrderDate = order.Attribute("OrderDate").Value,
    BillingAddress = new Address
    {
        City = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single().Element("City").Value,
        Country = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single().Element("Country").Value,
        Name = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single().Element("Name").Value,
        State = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single().Element("State").Value,
        Street = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single().Element("Street").Value,
        Type = "Billing",
        Zip = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single().Element("Zip").Value
    },
    ShippingAddress = new Address
    {
        City = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single().Element("City").Value,
        Country = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single().Element("Country").Value,
        Name = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single().Element("Name").Value,
        State = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single().Element("State").Value,
        Street = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single().Element("Street").Value,
        Type = "Shipping",
        Zip = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single().Element("Zip").Value
    },
    DeliveryNotes = order.Element("DeliveryNotes").Value,
    Items = null
});

首先,为什么“order.Element(”DeliveryNotes“)。值”在输出xml中不存在并抛出“对象引用未设置为对象的实例”?

其次,如何获取地址的“类型”(属性)?

第三,如何将项目列表设置为“Items = null”,以便我有一个功能齐全的对象可供使用?

最后如果linq的其余部分需要进行调整,那么请继续向我指导正确的方向; o)

1 个答案:

答案 0 :(得分:1)

<强>更新 我重写了代码,因此它现在不使用value属性。它还应填充您的Items列表。

我发现这个主题非常有用:

LINQ to XML optional element query

How do you guard for Null Reference exceptions in Linq To Xml?

var doc = XDocument.Load(@"C:\Temp\stackoverflow.xml");

var ordersTemp = 
    (from order in doc.Descendants("PurchaseOrder") select 
            new {
                order,
                BillingAddress = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Billing").Single(),
                ShippingAddress = order.Descendants("Address").Where(a => a.Attribute("Type").Value == "Shipping").Single(),
                Items = order.Descendants("Items").Descendants("Item")
            });

var orders = (from order in ordersTemp select  
    new PurchaseOrder
    {
        PurchaseOrderNumber = (string)order.order.Attribute("PurchaseOrderNumber"),
        OrderDate = (string)order.order.Attribute("OrderDate"),
        BillingAddress = new Address
        {
            City = (string)order.BillingAddress.Element("City"),
            Country = (string)order.BillingAddress.Element("Country"),
            Name = (string)order.BillingAddress.Element("Name"),
            State = (string)order.BillingAddress.Element("State"),
            Street = (string)order.BillingAddress.Element("Street"),
            Type = "Billing",
            Zip = (string)order.BillingAddress.Element("Zip")
        },
        ShippingAddress = new Address
        {
            City = (string)order.ShippingAddress.Element("City"),
            Country = (string)order.ShippingAddress.Element("Country"),
            Name = (string)order.ShippingAddress.Element("Name"),
            State = (string)order.ShippingAddress.Element("State"),
            Street = (string)order.ShippingAddress.Element("Street"),
            Type = "Shipping",
            Zip = (string)order.ShippingAddress.Element("Zip")
        },
        DeliveryNotes = (string)order.order.Element("DeliveryNotes"),
        Items = (from item in order.Items select new Item
        {
            PartNumber = (string)item.Attribute("PartNumber"),
            ProductName = (string)item.Element("ProductName"),
            Quantity = (string)item.Element("Quantity"),
            USPrice = (string)item.Element("USPrice"),
            Comment = (string)item.Element("Comment")
        }).ToList()
    });