Reputation: 1105
I'm working on a Silverlight web application that works with XML similar to:
<?xml version="1.0" encoding="UTF-8" ?>
<ProjectList>
<Type>web</Type>
<Project>
<Id>1</Id>
<Name>test web project</Name>
<Description>test web project</Description>
<ScreenshotList>
<Screenshot>
<Path>screen1.jpg</Path>
<Description>This a description of screen 1</Description>
</Screenshot>
<Screenshot>
<Path>screen2.jpg</Path>
<Description>This a description of screen 2</Description>
</Screenshot>
<Thumb>noThumb.jpg</Thumb>
</ScreenshotList>
</Project>
</ProjectList>
I would like to create a new object for each Project element in the XML. I have a class called project which contains fields for id, name, description, thumb and a list for all the screenshots.
My current LINQ code looks like:
var projects = from project in xDoc.Root.Elements("Project")
select new Project(
Int32.Parse(project.Element("Id").Value, CultureInfo.InvariantCulture),
project.Element("Name").Value,
project.Element("Description").Value,
project.Element("ScreenshotList").Element("Thumb").Value
);
Is there anyway for me to easily get the screenshots and add them to the list in the instance of Project within this one query?
EDIT - Adding Project constructorpublic Project(int id, string name, string description, string thumbPath)
{
this.id = id;
this.name = name;
this.description = description;
this.thumbPath = thumbPath;
}
Upvotes: 1
Views: 460
Reputation: 1062745
Something like:
var projects = from project in xDoc.Root.Elements("Project")
let list = project.Element("ScreenshotList")
select new Project(
(int) project.Element("Id"),
(string)project.Element("Name"),
(string)project.Element("Description"),
(string)list.Element("Thumb"),
from scr in list.Elements("Screenshot")
select new Screenshot(
(string)scr.Element("Path"),
(string)scr.Element("Description")
)
);
Based on types like:
class Project {
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Thumb { get; set; }
public List<Screenshot> Screenshots { get; private set; }
public Project( int id, string name, string description, string thumb,
IEnumerable<Screenshot> screenshots) {
this.Id = id;
this.Name = name;
this.Description = description;
this.Thumb = thumb;
this.Screenshots = screenshots == null ? new List<Screenshot>()
: new List<Screenshot>(screenshots);
}
}
class Screenshot {
public string Path { get; set; }
public string Description { get; set; }
public Screenshot(string path,string description) {
this.Path = path;
this.Description = description;
}
}
Upvotes: 3
Reputation: 1500385
Well, you haven't shown what the Project constructor looks like... does it let you pass in the screenshots as an IEnumerable<Screenshot>
? If so, it should be easy... something like:
var projects =
from p in xDoc.Root.Elements("Project")
select new Project(Int32.Parse(project.Element("Id").Value,
CultureInfo.InvariantCulture),
p.Element("Name").Value,
p.Element("Description").Value,
p.Element("ScreenshotList")
.Element("Thumb").Value,
p.Element("ScreenshotList")
.Elements("Screenshot")
.Select(ss =>
new Screenshot(ss.Element("Path").Value,
ss.Element("Description").Value))
);
(I've reformatted a bit to avoid scrolling.)
Upvotes: 2