2013-10-24 58 views
1

我有一个这样的XML:使用LINQ来元组的XML元素?

<?xml version="1.0" encoding="Windows-1252"?> 
<!--XML Songs Database.--> 
<Songs> 
    <Song><Name>My Song 1.mp3</Name><Year>2007</Year><Genre>Dance</Genre><Bitrate>320</Bitrate><Length>04:55</Length><Size>4,80</Size></Song> 
    <Song><Name>My Song 2.mp3</Name><Year>2009</Year><Genre>Electro</Genre><Bitrate>192</Bitrate><Length>06:44</Length><Size>8,43</Size></Song> 
    <Song><Name>My Song 3.mp3</Name><Year>2008</Year><Genre>UK Hardcore</Genre><Bitrate>128</Bitrate><Length>05:12</Length><Size>4,20</Size></Song> 
</Songs> 

我想存储的元素放进一个数组或类似容易阅读他们的东西。

我认为元组的Lis将是一个很好的集合“容器”,如果不是,那么我可以听到建议。

我做了转换,但没有使用LINQ,我想简化下面创建的元组使用LINQ的列表,而不是使用FOR +选择情况下的代码,所以我需要帮助重写/改善这个代码:

Dim Name As String = String.Empty 
Dim Year As String = String.Empty 
Dim Genre As String = String.Empty 
Dim Bitrate As String = String.Empty 
Dim Length As String = String.Empty 
Dim Size As String = String.Empty 

Dim SongsList As New List(Of Tuple(Of String, String, String, String, String, String)) 
Dim Elements As IEnumerable(Of XElement) = XDocument.Load(xmlfile).Descendants() 

For Each Element As XElement In Elements 

    Select Case Element.Name 

     Case "Name" 
      Name = Element.Value 
     Case "Year" 
      Year = Element.Value 
     Case "Genre" 
      Genre = Element.Value 
     Case "Bitrate" 
      Bitrate = Element.Value 
     Case "Length" 
      Length = Element.Value 
     Case "Size" 
      Size = Element.Value 
      SongsList.Add(Tuple.Create(Name, Year, Genre, Bitrate, Length, Size)) 

    End Select 

Next 

,并阅读的歌曲我这样做:

For Each song As Tuple(Of String, String, String, String, String, String) In SongsList 

    MsgBox(String.Format("Name:{1}{0}Year:{2}{0}Genre:{3}{0}Bitrate:{4}{0}Length:{5}{0}Size:{6}", _ 
         Environment.NewLine, _ 
         song.Item1, song.Item2, song.Item3, song.Item4, song.Item5, song.Item6)) 

    ' Output: 
    ' 
    ' Name:My Song 1.mp3 
    ' Year:2007 
    ' Genre:Dance 
    ' Bitrate:320 
    ' Length:04:55 
    ' Size:4,80 

Next 

回答

1

这是那么容易,因为

Dim xml = <?xml version="1.0" encoding="Windows-1252"?> 
      <!--XML Songs Database.--> 
      <Songs> 
       <Song><Name>My Song 1.mp3</Name><Year>2007</Year><Genre>Dance</Genre><Bitrate>320</Bitrate><Length>04:55</Length><Size>4,80</Size></Song> 
       <Song><Name>My Song 2.mp3</Name><Year>2009</Year><Genre>Electro</Genre><Bitrate>192</Bitrate><Length>06:44</Length><Size>8,43</Size></Song> 
       <Song><Name>My Song 3.mp3</Name><Year>2008</Year><Genre>UK Hardcore</Genre><Bitrate>128</Bitrate><Length>05:12</Length><Size>4,20</Size></Song> 
      </Songs> 

Dim result = from song in xml.<Songs>.<Song> 
      select Tuple.Create(song.<Name>.Value, 
           song.<Year>.Value, 
           song.<Genre>.Value, 
           song.<Bitrate>.Value, 
           song.<Length>.Value, 
           song.<Size>.Value) 

但不是怪物Tuple,你也可以使用匿名类型。这很容易为

Dim result = from song in xml.<Songs>.<Song> 
      select new with {song.<Name>.Value, 
           song.<Year>.Value, 
           song.<Genre>.Value, 
           song.<Bitrate>.Value, 
           song.<Length>.Value, 
           song.<Size>.Value} 

这样你就可以像用一个有意义的名称访问NameYearGenre等:

For Each song In result 
    Console.WriteLine(String.Format("Name:{1}{0}Year:{2}{0}Genre:{3}{0}Bitrate:{4}{0}Length:{5}{0}Size:{6}", _ 
            Environment.NewLine, _ 
            song.Name, song.Year, song.Genre, song.Bitrate, song.Length, song.Size)) 
Next 

,而不是无意义Item1Item2Item3

+0

三江源,在这里:'歌曲。 .Value'我可以使用某种Ignorecase作为“'Name'”字符串? (在将来写入这些字符串时,为了防止出现语法错误,这是一个100%完美的代码)。 – ElektroStudios

+2

@ElektroStudios否。因为XML区分大小写,所以会做错误的事情。因此,''标签与''标签不同,如果您的应用程序开始处理不同于标准的XML,它可能会非常麻烦。 – sloth

+0

这是一个完美的想法匿名类型!,是我第一次看到,你能说这是哪里正确的声明类型?:'对于每首歌作为<匿名类型>在结果中# – ElektroStudios