2011-02-09 27 views
0

我有兩個類 - CdTrack,我試圖從一個XML文件使用Linq讀入。LINQ to XML初始化數組

public Cd(string t, string a, string cat, DateTime rls, Track[] tr)
public Track(string t, int l)

的XML看起來是這樣的。

 
<media> 
    <cd> 
    <artist>Ozzy Osbourne</artist> 
    <album Name="Bark at the moon" Type="Metal" Tracks="5" ReleaseDate="1983-12-10"> 
     <track Length="300">Bark at the moon</track> 
     <track Length="235">You're No Different</track> 
     <track Length="567">Now You See It (Now You Don't)</track> 
     <track Length="356">Rock 'N' Roll Rebel</track> 
     <track Length="120">Centre of Eternity</track> 
    </album> 
    </cd> 
    <cd> 
    <artist>Journey</artist> 
    <album Name="Escape" Type="Rock" Tracks="4" ReleaseDate="1981-07-31"> 
     <track Length="300">Don't Stop Believin'</track> 
     <track Length="235">Stone in Love</track> 
     <track Length="567">Who's Crying Now</track> 
     <track Length="356">Keep on Runnin'</track> 
    </album> 
    </cd> 
</media> 

我試圖使用的代碼如下

 
XElement xdoc = XElement.Load("dbxml.xml"); 
    var temp = from cds in xdoc.Descendants("cd") 
    select new Cd(
     cds.Element("artist").Value, 
     cds.Element("album").Attribute("Name").Value, 
     cds.Element("album").Attribute("Type").Value, 
     DateTime.Parse(cds.Element("album").Attribute("ReleaseDate").Value), 
     new Track[] { // One Track reads fine.. 
      new Track(cds.Element("album").Element("track").Value, 
       int.Parse(cds.Element("album").Element("track").Attribute("Length").Value)) 
       } 
     ); 

的問題是,我不知道如何將陣列從XML文件中讀取的所有曲目初始化。我可以將整個查詢包裝在.ToList()中,使用anonomyous類型和foreach-但我想知道是否有一種方法可以在linq中進行一次運行。

cds.Elements("album").Elements("song")返回一個IEnumerable<XElement>集合,並以某種方式將其作爲範圍添加到數組中,並轉換爲一個字符串和一個int值,或者影響它的值。有什麼幫助嗎?

謝謝!使用屬性

XElement xdoc = XElement.Load("test.xml"); 
var temp = from cds in xdoc.Descendants("cd") 
      select new Cd(
       cds.Element("artist").Value, 
       cds.Element("album").Attribute("Name").Value, 
       cds.Element("album").Attribute("Type").Value, 
       DateTime.Parse(cds.Element("album").Attribute("ReleaseDate").Value), 
       cds.Element("album").Descendants("track").Select(t => new Track(t.Value, int.Parse(t.Attribute("Length").Value))).ToArray() 
       ); 

更易於讀取(IMO):

回答

1

這會工作

select new Cd() 
    { 
     Artist = cds.Element("artist").Value, 
     Album = cds.Element("album").Attribute("Name").Value, 
     Type = cds.Element("album").Attribute("Type").Value, 
     ReleaseDate = DateTime.Parse(cds.Element("album").Attribute("ReleaseDate").Value), 
     Tracks = cds.Element("album") 
        .Descendants("track") 
        .Select(t => new Track() 
        { 
         Name = t.Value, 
         Length = int.Parse(t.Attribute("Length").Value) 
        }).ToArray() 
    }; 

您應該考慮在CdTrack中添加默認構造函數,並公開屬性或使用命名參數 - 這會使LINQ語句更具可讀性。

0

在你的LINQ,更換

new Track[] { // One Track reads fine.. 
    new Track(cds.Element("album").Element("track").Value, 
     int.Parse(cds.Element("album").Element("track").Attribute("Length").Value)) 
     } 

像這樣的東西:

(from t in cds.Element("album").Elements("track") 
    select new Track(..., ...) 
).ToArray() 
+0

謝謝!雖然我得到了所有剩餘曲目重複的每張專輯的第一首曲目。五個月亮和四個樹皮不要停止信仰'。也許我搞砸了嗎? – citizencane 2011-02-09 20:54:33

+0

我錯了元素和IIRC它是你想要的元素。 BrokenGlass的答案是使用.Descendants,這可能是更好的方法。 – ongle 2011-02-09 21:19:08