2009-10-13 89 views
1

我工作的一个Silverlight Web应用程序,类似于XML的工作原理:的Silverlight C#的LINQ to XML

<?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> 

我想创建一个新的对象为XML中的每个项目元素。我有一个名为project的类,其中包含id,name,description,thumb和所有屏幕截图的列表字段。

我当前的LINQ代码如下所示:

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 
            ); 

反正对我来说,很容易得到的截图,这一个查询内项目的实例将它们添加到列表中?

编辑 - 添加项目构造
public Project(int id, string name, string description, string thumbPath) 
{ 
    this.id = id; 
    this.name = name; 
    this.description = description; 
    this.thumbPath = thumbPath; 
} 
+0

注意你并不需要所有的'Int32.Parse({expr}的。价值)' - 你可以只投了'XElement' - 简单得多,并给出了更清晰的米西行为ng元素(你可以强制转换为null等) – 2009-10-13 19:29:55

+0

对于信息 - 使用强制转换(而不是解析)的另一个原因; 'DateTime' - 如果您投了,它会使用正确的xsd日期格式;-p – 2009-10-13 19:44:38

+0

是的。比较查询,使用转换比解析更容易阅读。 – Jason 2009-10-14 14:47:28

回答

3

喜欢的东西:

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") 
         ) 
        ); 

基于类型,如:

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; 
    } 
} 
+0

你的解决方案很成功,但我给了Jon Skeet一个标记,因为他先到了那里。谢谢 – Jason 2009-10-13 19:39:17

+0

实际上,再次查看它,我更喜欢这个查询。你得到剔号! – Jason 2009-10-14 14:46:27

2

好了,你还没有显示的项目构造是什么样的......它让你在截图作为IEnumerable<Screenshot>通过?如果是这样,它应该很容易......是这样的:

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)) 
        ); 

(我已经重新格式化了一下,以避免滚动。)

+0

我添加了我目前的构造函数。我会尝试将它们作为参数传递给它。 – Jason 2009-10-13 19:25:52

+0

工作:)谢谢! – Jason 2009-10-13 19:36:23