2009-10-13 84 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