Steeven_b
Steeven_b

Reputation: 777

C# XML XDocument

I am coding a media player in C# so I saved playlists in an XML as below :

XML

So I want to get attributes of playlist "name" and attribute of media "path".

I am able to get both using this code :

var xdoc = XDocument.Load(@"mypath");

var names = from i in xdoc.Descendants("playlist")
            select new
            {
                Path = (string)i.Attribute("name")
            };

var paths = from i in xdoc.Descendants("media")
            select new
            {
                Path = (string)i.Attribute("path")
            };

foreach (var name in names)
{
    System.Diagnostics.Debug.WriteLine(name.Path);
    foreach (var path in paths)
        System.Diagnostics.Debug.WriteLine(path.Path);
}

So I get this :

Films

E:\Projets\CS - MyWindowsMediaPlayer\Example Medias\Music1.mp3
E:\Projets\CS - MyWindowsMediaPlayer\Example Medias\MusicInfos1.mp3
E:\Projets\CS - MyWindowsMediaPlayer\Example Medias\Video2.mp4
E:\Projets\CS - MyWindowsMediaPlayer\Example Medias\Video1.mp4
E:\Projets\CS - MyWindowsMediaPlayer\Example Medias\Video3.mp4

But I want to sort by categories, for example getting only links that corresponds with films.

Upvotes: 4

Views: 184

Answers (1)

Alberto Monteiro
Alberto Monteiro

Reputation: 6229

Lets use a combination with SelectMany and GroupBy.

The SelectMany will create a single list, with a tuple containing the playlist name and the media path, then we use GroupBy to group this list by playlist name, and finally we can use the Where to filter only the playlist with a given name, in this case, Films.

var xdoc = XDocument.Load(@"mypath");

var paths = xdoc.Descendants("playlist")
                .SelectMany(x => x.Descendants("media"), (pl, media) => Tuple.Create(pl.Attribute("name").Value, media.Attribute("path").Value))
                .GroupBy(x => x.Item1)
                .ToList();

foreach (var name in paths.Where(x => x.Key == "Films"))
{
    Console.WriteLine(name.Key);
    foreach (var tuple in name)
    {
        Console.WriteLine(tuple.Item2);
    }
}

Upvotes: 4

Related Questions