Reputation: 11975
I've an xml file as follows:
<ProductGroup>
<Product id="4601A">
<name>Roses</name>
<section>Floral</section>
<price>46</price>
<PopupImages>
<PopupImage>img1.jpg</PopupImage>
<PopupImage>img2.jpg</PopupImage>
</PopupImages>
<ImageThumbs>
<thumb>img1-thm.jpg</thumb>
<thumb>img2-thm.jpg</thumb>
</ImageThumbs>
</Product>
</ProductGroup>
In production the ProductGroup node might contain many Product nodes. For this I kind of want to build a list of an anonymous object that has the following properties:
name
section
image
thumb
I am able to get a list of Product elements using XDocument.
Dim doc As XDocument = XDocument.Load("ProductsGroups.xml")
Dim lstProducts = from x In doc Where CType(c.Element("price"), Integer) < 54
From here what do I do?
Update:
Let me explain this better. I am not sure if I have communicated this properly.
Taking the above xml example itself. The above code I've written returns all product elements with the specified "where" condition. Now for each XmlElement returned (product) I've to create n-number of anonymous objects. The number n depends on how many children are there for the PopupImages and ImageThumbs nodes. In my case however, the number will be the same. Hence coming back to the above example, I'd get two anonymous objects:
Anonymous1 Anonymous2
---------- ----------
name Roses Roses
section Floral Floral
image img1.jpg img2.jpg
thumb img1-thm.jpg img2-thm.jpg
Upvotes: 1
Views: 1447
Reputation: 418
I'm not familiar with VB.Net, but in C# you'd write something like this:
XDocument doc = XDocument.Load("D:\\file.xml");
var lstProducts = from XElement elem in doc.Element("ProductGroup").Elements("Product")
where int.Parse(elem.Element("price").Value) < 54
select new
{
name = elem.Element("name").Value,
section = elem.Element("section").Value,
image = elem.Element("PopupImages").Element("PopupImage").Value,
thumb = elem.Element("ImageThumbs").Element("thumb").Value
};
Hope this helps.
EDIT: new query that should handle merging PopupImages and ImageThumbs:
var lstProducts = from XElement elem in doc.Element("ProductGroup").Elements("Product")
where int.Parse(elem.Element("price").Value) < 54
let images = elem.Element("PopupImages").Elements("PopupImage")
let thumbs = elem.Element("ImageThumbs").Elements("thumb")
from img in images.Select(
(im, idx) => new KeyValuePair<string, string>(im.Value, thumbs.ElementAt(idx).Value)
)
select new
{
name = elem.Element("name").Value,
section = elem.Element("section").Value,
image = img.Key,
thumb = img.Value
};
Still in C#, but I think the idea is clear.
Upvotes: 0
Reputation: 96477
Try this approach:
Dim query = From product In doc.Elements("Product")
Where Integer.Parse(product.Element("price").Value) < 54
Select New With
{
.Name = product.Element("name").Value,
.Section = product.Element("section").Value,
.Images = product.Descendants("PopupImage").Select(Function(i) i.Value),
.Thumbs = product.Descendants("thumb").Select(Function(t) t.Value)
}
For Each item in query
Console.WriteLine(item.Name)
Console.WriteLine(item.Section)
Console.WriteLine("Images:")
For Each image in item.Images
Console.WriteLine(" " + image)
Next
Console.WriteLine("Thumbs:")
For Each thumb in item.Thumbs
Console.WriteLine(" " + thumb)
Next
Next
If you really need a list just call query.ToList()
and store the result in a variable or enclose the original query in parentheses and append ToList()
(I prefer not to do this for readability). Similarly, the images and thumbnails are currently of type IEnumerable<string>
, so if you need a list or array add the appropriate extension method call.
Upvotes: 1