linq to xml初始化数组

发布于 2024-10-16 19:48:17 字数 2132 浏览 3 评论 0原文

我有两个类 - CdTrack,我正在尝试使用 Linq 从 XML 文件中读取它们。

public Cd(字符串 t, 字符串 a, 字符串 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() 中,使用匿名类型和 foreach-it 但我想知道是否有办法做到这一点只需用 linq 运行一次即可。

cds.Elements("album").Elements("song") 返回一个 IEnumerable 集合,并且以某种方式应将其作为范围添加到数组中并转换转换成字符串和整数,或者其他有影响的东西。有什么帮助吗?

谢谢!

I have two classes - Cd and Track which I'm trying to read into from a XML file using Linq.

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

The XML looks like this.

<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>

The code I'm trying to use is as follows

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)) 
               }
        );

The problem is that I don't know how to initialize the array with all the tracks read from the XML file. I could wrap the whole query in a .ToList(), use an anonomyous type and foreach-it but I'd like to know if there is a way to do this in just one run with linq.

cds.Elements("album").Elements("song") returns an IEnumerable<XElement> collection and somehow that should be added to the array as a range and turned into a string and an int, or something to that affect. Any help out there?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浊酒尽余欢 2024-10-23 19:48:17

这会起作用:

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):

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 语句更具可读性。

This would work:

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() 
                );

Easier to read (imo) using properties:

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()
    };

You should consider adding a default constructor to Cd and Track and exposing public properties or use named parameters - this would make the LINQ statement much more readable.

故人如初 2024-10-23 19:48:17

在您的 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()

In your LINQ, replace

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

with something like this:

( from t in cds.Element("album").Elements("track") 
  select new Track(..., ...)
).ToArray()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文