将 IEnumerable<XElement> 转换为 List<nested object>
Convert IEnumerable<XElement> to List<nested object>
我看过几个讨论帖 (like this one or this 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 我创建了这个 class 现在我需要得到一个 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
。
像这样使用 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...
}
});
为什么不尝试将 xml 序列化为对象列表,它更短更清晰
创建基础对象
public class ListOfCustomers
{
[XmlElement("Customer")]
public List<DistributorCustomer> Customer { get; set; }
}
然后
XmlSerializer ser = new XmlSerializer(typeof(ListOfCustomers));
FileStream myFileStream = new FileStream(/*file path*/); //if you are using a file. use Memory stream for xml string
var thelist = (ListOfCustomers)ser.Deserialize(myFileStream);
OP在这里。我将把 DavidG 的答案作为正确答案,因为他会引导我找到解决方案。但我也想post这里的整个答案,只是为了post严肃。
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();
我看过几个讨论帖 (like this one or this 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 我创建了这个 class 现在我需要得到一个 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
。
像这样使用 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...
}
});
为什么不尝试将 xml 序列化为对象列表,它更短更清晰
创建基础对象
public class ListOfCustomers
{
[XmlElement("Customer")]
public List<DistributorCustomer> Customer { get; set; }
}
然后
XmlSerializer ser = new XmlSerializer(typeof(ListOfCustomers));
FileStream myFileStream = new FileStream(/*file path*/); //if you are using a file. use Memory stream for xml string
var thelist = (ListOfCustomers)ser.Deserialize(myFileStream);
OP在这里。我将把 DavidG 的答案作为正确答案,因为他会引导我找到解决方案。但我也想post这里的整个答案,只是为了post严肃。
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();