我如何获得数组的数组使用Linq到XML
本文关键字:数组 Linq XML 何获得 | 更新日期: 2023-09-27 18:15:31
如何获得所有类型的列表?现在我只能得到每首歌的第一种类型。
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#代码: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);
}
}
结果:Pop
Rock
但是我需要:
Rock
American
Pop
Unplugged
谢谢。
由于您没有执行任何过滤器,您可以直接使用Descendants
如下:-
XDocument xLibrary = XDocument.Load(@"c:'Library.xml");
IEnumerable<string> result = xLibrary.Descendants("Genre").Select(x => (string)x);
或者如果你喜欢查询语法:-
IEnumerable<string> res = from genre in xdoc.Descendants("Genre")
select (string)genre;
您需要为此导入using System.Linq;
。这将产生您期望的输出,即Rock American Pop Unplugged,即使它没有被排序。你可以用order by
来代替。
检查这个答案,了解为什么我使用Descendants
而不是Elements
。
如果您不需要任何额外的类型过滤,您可以轻松地获得文档中的所有类型,如下所示:
var genres = xLibrary.XPathSelectElements("//Genre").Select(g => g.Value);
注意:XPathSelectElements
是一个扩展方法,为了使用这个方法,请确保在源代码中使用System.Xml.XPath
命名空间。
如果您的xml还包含用于歌曲以外元素的"Genre"节点:
XDocument doc = XDocument.Parse(xml);
var genres = doc.Root.Element("Songs")
.Elements("Song")
.Elements("Genres")
.Elements("Genre")
.Select(e => e.Value);
假设您需要每首歌曲的类型排序列表。你可以试试下面的代码:
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);
}
}
试试这个
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();
}
}
}
IEnumerable<string> genres = xSongs.Elements("Song")
.Select(song => song.Element("Genres"))
.SelectMany(genres => genres.Elements("Genre"))
.Select(genre => genre.Value)
.OrderBy(x => x);
问题是你选择使用.Element(string)
的单一类型,如果你不想使用.Descendants(string)
,你应该使用.GetElements(string)
:
IEnumerable<string> genres = xSongs
.Elements("Song")
.SelectMany(song => song
.Element("Genres")
.Elements("Genre")
.Select(genre => genre.Value));
上面的linq等价于"xSongs.(many)Song.Genres.(many)Genre.Value"
如果你想使用查询语法:
IEnumerable<string> genres = from song in xSongs.Elements("Song")
let songGenres = song.Element("Genres").Elements("Genre")
from genre in songGenres
select genre.Value;
由于xml中有多个一对多关系,因此您需要在linq查询中有多个from