How I can get a list of all genres? Now I only get the first genre of each song.
我怎样才能得到所有流派的列表?现在我只知道每首歌的第一种类型。
XML file:
XML文件:
<Library xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Songs>
<Song>
<Title>High Hopes</Title>
<Genres>
<Genre>Rock</Genre>
<Genre>American</Genre>
</Genres>
</Song>
<Song>
<Title>Imagine</Title>
<Genres>
<Genre>Pop</Genre>
<Genre>Unplugged</Genre>
</Genres>
</Song>
</Songs>
</Library>
C# code:
c#代码:
public void ListGenres()
{
System.Xml.Linq.XElement xLibrary = System.Xml.Linq.XElement.Load(@"c:\Library.xml");
System.Xml.Linq.XElement xSongs = xLibrary.Element("Songs");
System.Collections.Generic.IEnumerable<string> genres =
from code in xSongs.Elements("Song")
let genre = (string)code.Element("Genres").Element("Genre")
orderby genre
select genre;
foreach (string genre in genres)
{
Console.WriteLine(genre);
}
}
Result:
结果:
Pop
Rock
But I need:
但我需要:
Rock
American
Pop
Unplugged
Thanks.
谢谢。
7 个解决方案
#1
3
Since you are not performing any filters, you can directly use Descendants
like this:-
由于您没有执行任何过滤器,您可以直接使用如下:-
XDocument xLibrary = XDocument.Load(@"c:\Library.xml");
IEnumerable<string> result = xLibrary.Descendants("Genre").Select(x => (string)x);
Or if you prefer query syntax:-
或者如果你喜欢查询语法:-
IEnumerable<string> res = from genre in xdoc.Descendants("Genre")
select (string)genre;
You need to import using System.Linq;
for this.This will produce the outpu you expect i.e. Rock American Pop Unplugged even though it is not ordered. You can always use order by
caluse for that.
您需要使用System.Linq导入。对于这个。这将产生你所期望的outpu,即摇滚美国流行的不插电,即使它没有被订购。你可以用caluse的顺序来做这个。
Check this answer to understand why I am using Descendants
instead of Elements
.
检查这个答案,以理解为什么我使用后代而不是元素。
#2
1
If you don't need any additional filtering of genres, you can easily get all the genres in document like this:
如果你不需要任何额外的体裁筛选,你可以很容易地得到所有体裁像这样的文件:
var genres = xLibrary.XPathSelectElements("//Genre").Select(g => g.Value);
Note: XPathSelectElements
is an extension method, make sure you're using System.Xml.XPath
namespace in your sourcecode in order to use this method.
注意:XPathSelectElements是一个扩展方法,确保您使用的是System.Xml。为了使用此方法,您的源代码中的XPath命名空间。
#3
1
In case your xml also contains "Genre" nodes for elements other than songs:
如果您的xml也包含除歌曲之外的元素的“类型”节点:
XDocument doc = XDocument.Parse(xml);
var genres = doc.Root.Element("Songs")
.Elements("Song")
.Elements("Genres")
.Elements("Genre")
.Select(e => e.Value);
#4
0
Assuming you need ordered list of genre for each song. You can try below code.
假设你需要为每首歌的类型排序列表。你可以试试下面的代码。
public void ListGenres()
{
System.Xml.Linq.XElement xLibrary = System.Xml.Linq.XElement.Load(@"c:\Library.xml");
System.Xml.Linq.XElement xSongs = xLibrary.Element("Songs");
System.Collections.Generic.IEnumerable<List<string>> genresList =
from code in xSongs.Elements("Song")
let genreList = (string)code.Element("Genres")
select genreList.ToList();
foreach (List<string> genreList in genresList)
{
var orderedList = genreList.OrderBy(x=>x);
foreach(string genre in orderedList)
Console.WriteLine(genre);
}
}
#5
0
Try this
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication52
{
class Program
{
static void Main(string[] args)
{
string input =
"<Library xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Songs>" +
"<Song>" +
"<Title>High Hopes</Title>" +
"<Genres>" +
"<Genre>Rock</Genre>" +
"<Genre>American</Genre>" +
"</Genres>" +
"</Song>" +
"<Song>" +
"<Title>Imagine</Title>" +
"<Genres>" +
"<Genre>Pop</Genre>" +
"<Genre>Unplugged</Genre>" +
"</Genres>" +
"</Song>" +
"</Songs>" +
"</Library>";
XElement library = XElement.Parse(input);
var results = library.Descendants("Song").Select(x => new
{
title = x.Element("Title").Value,
genres = x.Descendants("Genre").Select(y => new {
genere = y.Value
}).ToList()
}).ToList();
}
}
}
#6
0
IEnumerable<string> genres = xSongs.Elements("Song")
.Select(song => song.Element("Genres"))
.SelectMany(genres => genres.Elements("Genre"))
.Select(genre => genre.Value)
.OrderBy(x => x);
#7
0
The problem is you are selecting a single genre using .Element(string)
, you should use .GetElements(string)
if you dont wanna use .Descendants(string)
:
问题是你正在使用。element (string)选择一个类型,如果你不想使用。descendants (string):
IEnumerable<string> genres = xSongs
.Elements("Song")
.SelectMany(song => song
.Element("Genres")
.Elements("Genre")
.Select(genre => genre.Value));
The linq above is equivalent to "xSongs.(many)Song.Genres.(many)Genre.Value"
上面的linq相当于“xSongs.(许多)歌曲。类型。(many)Genre.Value”
And if you rather use query syntax:
如果你更喜欢使用查询语法:
IEnumerable<string> genres = from song in xSongs.Elements("Song")
let songGenres = song.Element("Genres").Elements("Genre")
from genre in songGenres
select genre.Value;
Since you have more than one one-to-many relation in your xml, you need to have more than one from
in your linq query.
由于在xml中有多个一对多关系,所以在linq查询中需要多个关系。
#1
3
Since you are not performing any filters, you can directly use Descendants
like this:-
由于您没有执行任何过滤器,您可以直接使用如下:-
XDocument xLibrary = XDocument.Load(@"c:\Library.xml");
IEnumerable<string> result = xLibrary.Descendants("Genre").Select(x => (string)x);
Or if you prefer query syntax:-
或者如果你喜欢查询语法:-
IEnumerable<string> res = from genre in xdoc.Descendants("Genre")
select (string)genre;
You need to import using System.Linq;
for this.This will produce the outpu you expect i.e. Rock American Pop Unplugged even though it is not ordered. You can always use order by
caluse for that.
您需要使用System.Linq导入。对于这个。这将产生你所期望的outpu,即摇滚美国流行的不插电,即使它没有被订购。你可以用caluse的顺序来做这个。
Check this answer to understand why I am using Descendants
instead of Elements
.
检查这个答案,以理解为什么我使用后代而不是元素。
#2
1
If you don't need any additional filtering of genres, you can easily get all the genres in document like this:
如果你不需要任何额外的体裁筛选,你可以很容易地得到所有体裁像这样的文件:
var genres = xLibrary.XPathSelectElements("//Genre").Select(g => g.Value);
Note: XPathSelectElements
is an extension method, make sure you're using System.Xml.XPath
namespace in your sourcecode in order to use this method.
注意:XPathSelectElements是一个扩展方法,确保您使用的是System.Xml。为了使用此方法,您的源代码中的XPath命名空间。
#3
1
In case your xml also contains "Genre" nodes for elements other than songs:
如果您的xml也包含除歌曲之外的元素的“类型”节点:
XDocument doc = XDocument.Parse(xml);
var genres = doc.Root.Element("Songs")
.Elements("Song")
.Elements("Genres")
.Elements("Genre")
.Select(e => e.Value);
#4
0
Assuming you need ordered list of genre for each song. You can try below code.
假设你需要为每首歌的类型排序列表。你可以试试下面的代码。
public void ListGenres()
{
System.Xml.Linq.XElement xLibrary = System.Xml.Linq.XElement.Load(@"c:\Library.xml");
System.Xml.Linq.XElement xSongs = xLibrary.Element("Songs");
System.Collections.Generic.IEnumerable<List<string>> genresList =
from code in xSongs.Elements("Song")
let genreList = (string)code.Element("Genres")
select genreList.ToList();
foreach (List<string> genreList in genresList)
{
var orderedList = genreList.OrderBy(x=>x);
foreach(string genre in orderedList)
Console.WriteLine(genre);
}
}
#5
0
Try this
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication52
{
class Program
{
static void Main(string[] args)
{
string input =
"<Library xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
"<Songs>" +
"<Song>" +
"<Title>High Hopes</Title>" +
"<Genres>" +
"<Genre>Rock</Genre>" +
"<Genre>American</Genre>" +
"</Genres>" +
"</Song>" +
"<Song>" +
"<Title>Imagine</Title>" +
"<Genres>" +
"<Genre>Pop</Genre>" +
"<Genre>Unplugged</Genre>" +
"</Genres>" +
"</Song>" +
"</Songs>" +
"</Library>";
XElement library = XElement.Parse(input);
var results = library.Descendants("Song").Select(x => new
{
title = x.Element("Title").Value,
genres = x.Descendants("Genre").Select(y => new {
genere = y.Value
}).ToList()
}).ToList();
}
}
}
#6
0
IEnumerable<string> genres = xSongs.Elements("Song")
.Select(song => song.Element("Genres"))
.SelectMany(genres => genres.Elements("Genre"))
.Select(genre => genre.Value)
.OrderBy(x => x);
#7
0
The problem is you are selecting a single genre using .Element(string)
, you should use .GetElements(string)
if you dont wanna use .Descendants(string)
:
问题是你正在使用。element (string)选择一个类型,如果你不想使用。descendants (string):
IEnumerable<string> genres = xSongs
.Elements("Song")
.SelectMany(song => song
.Element("Genres")
.Elements("Genre")
.Select(genre => genre.Value));
The linq above is equivalent to "xSongs.(many)Song.Genres.(many)Genre.Value"
上面的linq相当于“xSongs.(许多)歌曲。类型。(many)Genre.Value”
And if you rather use query syntax:
如果你更喜欢使用查询语法:
IEnumerable<string> genres = from song in xSongs.Elements("Song")
let songGenres = song.Element("Genres").Elements("Genre")
from genre in songGenres
select genre.Value;
Since you have more than one one-to-many relation in your xml, you need to have more than one from
in your linq query.
由于在xml中有多个一对多关系,所以在linq查询中需要多个关系。