【问题标题】:Linq to xml select new PurchaseOrderLinq to xml 选择新的 PurchaseOrder
【发布时间】:2012-11-01 16:35:23
【问题描述】:

我正试图让我的头脑围绕“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>

然后我创建了一些简单的对象:

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
});

首先,为什么输出 xml 中不存在“order.Element("DeliveryNotes").Value”,并抛出“Object reference not set to an instance of an object”?

二、如何获取地址的“类型”(即属性)?

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

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

【问题讨论】:

    标签: linq linq-to-xml


    【解决方案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()
        });
    

    【讨论】:

    • 您好 Roman,我尝试按照您的建议更新代码,但仍然没有收到 DeliveryNotes(仍然是同样的错误)。我知道如何创建 List 但它是空的。我要说的是如何从上面的 xml 文件中获取填充的数据?
    • 是的,现在我明白了。在我阅读了这个主题stackoverflow.com/questions/278215/… 之后,我稍微改变了一个答案。也来看看吧
    • 这对 DeliveryNotes 起到了作用。为了让项目工作,我必须将这个“order.Items”更改为“order.order.Descendants("Item")”,然后我加载了一个功能齐全的对象,可以在任何我想要的地方使用它。非常感谢;o)
    • 该死的,我忘记更改 orderTemp 部分,更改了 :) 如果您认为它适合您,请接受答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多