Reputation: 167
I have an XML document that can have multiple children elements under another element, and I was wondering how I can get all these elements and store as an object? For example-
<?xml version="1.0" encoding="utf-8" ?>
<export>
<order>
<ordernumber>100</ordernumber>
<items>
<item>
<name>table</name>
</item>
<item>
<name>chair</name>
</item>
</items>
</order>
</export>
So say I get all orders using LINQ and store in a list
var xdoc = XDocument.Load(myXMLReader);
var result = (from x in xdoc.Root.Elements()
select new Order
{
OrderNumber = (string)x.Element("OrderNumber")
}).ToList();
What do I need to do to the above to get ALL items in an order and store in another object property such as a List or something similar? EG.
var result = (from x in xdoc.Root.Elements()
select new Order
{
OrderNumber = (string)x.Element("OrderNumber")
//PSUEDO CODE ADDITION
Items = (new { Name = itemname}).ToList()
// END PSUEDO CODE ADDITION
}).ToList();
Upvotes: 1
Views: 3088
Reputation: 1561
Based on the root element being named export, I thought you might be trying to serialize/de-serialize objects in your program:
[XmlRoot("export")]
public class Export
{
[XmlElement("order")]
public Order order {get; set;}
}
public class Order
{
[XmlElement("ordernumber")]
public int orderNumber { get; set; }
[XmlArray("items"), XmlArrayItem("item")]
public Item[] items { get; set; }
}
public class Item
{
public string name { get; set; }
}
static void Serialize(string file, Export export)
{
var serializer = new XmlSerializer(typeof(Export));
using (var stream = File.Create(file))
serializer.Serialize(stream, export);
}
static Export Deserialize(string file)
{
var serializer = new XmlSerializer(typeof(Export));
using (var stream = File.OpenRead(file))
return (Export) serializer.Deserialize(stream);
}
You would call it like this:
var export = new Export
{
order = new Order
{
orderNumber = 100,
items = new[]
{
new Item {name = "table"},
new Item {name = "chair"}
}
}
};
Serialize("exported_orders.xml", export);
and like this:
var export = Deserialize("exported_orders.xml");
Upvotes: 0
Reputation: 21825
I think you need this:-
List<Order> orders = xdoc.Descendants("order")
.Select(x => new Order
{
OrderNumber = (string)x.Element("ordernumber"),
Items = x.Descendants("item")
.Select(i => new Item
{
Name = (string)i.Element("name") }).ToList()
}).ToList();
Type I have used:-
public class Order
{
public string OrderNumber { get; set; }
public List<Item> Items { get; set; }
}
public class Item
{
public string Name { get; set; }
}
Upvotes: 2
Reputation: 70701
I'm not entirely sure what you're trying to do. But I think it might be something like this:
var result = (from x in xdoc.Root.Elements()
select new Order
{
OrderNumber = (string)x.Element("ordernumber"),
Items = x.Element("items")
.Elements("item")
.Select(itemElement =>
new Item { Name = itemElement.Value })
.ToList()
}).ToList();
In other words: for the given element, first find the one items
child element, then from that element, select all of its item
child elements, and finally from that collection, project to a collection of Item
objects, to be materialized as a List<Item>
and assigned to the Order.Items
property.
(Note: you were mixing the named type Order
with the anonymous type representing an item
XML element; I fixed the code so that it uses named types everywhere, but you can of course use anonymous everywhere instead if you like).
Upvotes: 2