将IEnumerable <XElement>转换为List <嵌套对象>

时间:2019-07-30 15:13:06

标签: c# .net linq-to-xml

我看过几个线程(like this onethis one),它们显示了如何将XDocument转换为简单对象(例如字符串)的List<>。但是,我在如何使用嵌套对象来解决这个问题。

这是XML的样子……

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
.... other stuff removed to make reading easier ....
            <ListOfCustomers>
                <Customer>
                    <CustomerName>A TO Z Fubar</CustomerName>
                    <AccountNumber>A TO001</AccountNumber>
                    <BillingAddress>
                        <Address1>11900 W FUBAR AVE</Address1>
                        <Address2/>
                        <City>FUBAR</City>
                        <State>CO</State>
                        <Zip>80215</Zip>
                        <Country>US</Country>
                    </BillingAddress>
                    <ShippingAddress>
                        <Address1>11900 W FUBAR AVE</Address1>
                        <Address2/>
                        <City>FUBAR</City>
                        <State>CO</State>
                        <Zip>80215</Zip>
                        <Country>US</Country>
                    </ShippingAddress>
                </Customer>
                <Customer>....</Customer>
                <Customer>....</Customer>
            </ListOfCustomers>

然后从该XML中创建了一个此类,现在需要获得List<>的类...

public class DistributorCustomer
{
    public string CustomerName { get; set; }
    public string AccountNumber { get; set; }
    public BillingAddress BillingAddress { get; set; }
    public ShippingAddress ShippingAddress { get; set; }
}


public class BillingAddress
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }
}

public class ShippingAddress
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }
}

我正在Azure博客存储触发器功能中进行此操作。我已经走了这么远:

XDocument xDoc = XDocument.Load(blobFile);
IEnumerable<XElement> customers = xDoc.Descendants("Customer");

足够简单! customers实际上是XML文件中所有客户的全部IEnumerable。现在我只需要从一个

IEnumerable<XElement>

List<DistributorCustomer>

那我不确定该怎么做。从其他线程来看,这可以通过LINQ to XML实现,并且不需要在customers上循环。

3 个答案:

答案 0 :(得分:1)

使用Linq解析XML可能非常强大,也许不是最好的方法(自从我使用XML以来已有一段时间),但这是利用Linq Select将元素投影到类型中的一种方法:

var customers = xDoc.Descendants("Customer")
    .Select(c => new DistributorCustomer
    {
        CustomerName = c.Element("CustomerName").Value,
        AccountNumber = c.Element("AccountNumber").Value,
        BillingAddress = new BillingAddress
        {
            Address1 = c.Element("BillingAddress").Element("Address1").Value,
            // etc...
        }
    });

答案 1 :(得分:1)

为什么不尝试将xml序列化为对象列表,它又短又整洁

创建基础对象

A A B C D E F G H I A A A J K L B M N O A A A P A Q R A A 
1 1 2 3 4 5 6 7 8 9 9 1 1 2 3 4 5 6 7 8 8 1 1 2 2 3 4 3 1

然后

public class ListOfCustomers
{
    [XmlElement("Customer")]
    public List<DistributorCustomer> Customer { get; set; }
}

答案 2 :(得分:1)

在这里OP。我将把DavidG的答案留作正确答案,因为他带领我找到了解决方案。但我也想将整个答案都张贴在这里,仅供后人参考。

            List<DistributorCustomer> customerList = xDoc.Descendants("Customer")
            .Select(c => new DistributorCustomer
            {
                CustomerName = c.Element("CustomerName")?.Value,
                AccountNumber = c.Element("AccountNumber")?.Value,
                BillingAddress = new BillingAddress
                {
                    Address1 = c.Element("BillingAddress")?.Element("Address1")?.Value,
                    Address2 = c.Element("BillingAddress")?.Element("Address2")?.Value,
                    City = c.Element("BillingAddress")?.Element("City")?.Value,
                    State = c.Element("BillingAddress")?.Element("State")?.Value,
                    Zip = c.Element("BillingAddress")?.Element("Zip")?.Value,
                    Country = c.Element("BillingAddress")?.Element("Country")?.Value,
                },
                ShippingAddress = new ShippingAddress
                {
                    Address1 = c.Element("ShippingAddress")?.Element("Address1")?.Value,
                    Address2 = c.Element("ShippingAddress")?.Element("Address2")?.Value,
                    City = c.Element("ShippingAddress")?.Element("City")?.Value,
                    State = c.Element("ShippingAddress")?.Element("State")?.Value,
                    Zip = c.Element("ShippingAddress")?.Element("Zip")?.Value
                }
            }).ToList();