LINQ到XML - 如何使用的XDocument的正确方法 [英] LINQ to XML - How to use XDocument the right way

查看:191
本文介绍了LINQ到XML - 如何使用的XDocument的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我会说这确实是一个assigment开始。我已经然而接近完成它,直到我跑进的LINQ to XML语法

Now I will start off by saying this is indeed an assigment. I have however nearly finished it untill I ran into the Linq to XML syntax.

我有2类:跟踪和CD现在作为assigment的一部分,我创建了一个光盘,然后增加了一些曲目给它。 。寻找很多的教程后,完美解释了如何从XML对象去,我似乎无法得到这个工作(对象到XML)

I have 2 classes: Track and CD now as part of the assigment I create a cd and then added some tracks to it. After searching for lots of tutorials that explained perfectly how to go from xml to objects I just cannot seem to get this working (objects to xml).

我目前有:

//My list of cds
List<CD> cds = new List<CD>();
//Make a new CD and add some tracks to it
CD c1 = new CD("Awake","Dream Theater");
Track t1 = new Track("6:00", "Dream Theater", new TimeSpan(00, 05, 31));
Track t2 = new Track("Caught in a Web", "Dream Theater", new TimeSpan(00, 05, 28));
Track t3 = new Track("Innocence Faded", "Dream Theater", new TimeSpan(00, 05, 34));
c1.addTrack(t1);
c1.addTrack(t2);
c1.addTrack(t3);
cds.Add(c1);

//Make another cd and add it
CD c2 = new CD("Second cd","TestArtist");
Track t4 = new Track("TrackForSecond","TestArtist",new TimeSpan(00,13,37));
c2.addTrack(t4);
cds.add(c2);

现在这是什么打动了我,我需要投入XML的对象。在对XML的部分是:

Now this is what gets me the objects I need to put into XML. The to XML part is:

XDocument xmlOutput = new XDocument (
     new XDeclaration("1.0","utf-8","yes"),
     (from cl in cds orderby cl.getArtist()
        select new XElement("cd",  /*From new to the end of this is the error*/
            (
               from c in cds
                   select new XAttribute("artist",c.getArtist())
            ),
            (
               from c in cds
                   select new XAttribute("name", c.getTitle())
            ),
            new XElement("tracks",
               (
                   from t in c1.getTracks()
                       select new XElement("track",
                           new XElement("artist",t1.getArtist()),    
                           new XElement("title",t1.getTitle()),
                           new XElement("length",t1.getLength())
                       )          
               )                    
            )
        )
    )                   
);
Console.WriteLine(xmlOutput);

这伟大工程(得到我的结果,我需要!)只需1张CD。当我决定要添加另一张CD它表明:

This works great (gets me the result I need!) for just 1 cd. When I decide to add another cd it shows:

An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.Linq.dll
Duplicate Attribute (cd)

这是在指点的XDocument。除了这个不工作,感觉非常愚蠢的(从C在CDS×2),但无论我尝试,我似乎无法从恨我停止这种语法:

Which is pointing at the XDocument. Aside from this not working it feels pretty stupid (from c in cds x2) but whatever I try I cannot seem to stop this syntax from hating me:

(
from c in cds
   select new XAttribute("artist",c.getArtist()),    
   select new XAttribute("name", c.getTitle()) //No not happening!
),

会很乐意与任何帮助你可以提供!

Would be very happy with any help you can provide!

推荐答案

首先,我建议你使用属性和C#风格命名的方法。这里是你的班如何进行重构:

First, I suggest you to use properties and C# style naming for methods. Here is how your classes could be refactored:

public class CD
{
    private readonly List<Track> _tracks = new List<Track>();

    public CD(string artist, string title)
    {
        Artist = artist;
        Title = title;
    }

    public string Artist { get; private set; }
    public string Title { get; private set; }

    public  IEnumerable<Track> Tracks
    {
        get { return _tracks; }
    } 

    public void AddTrack(Track track)
    {
        _tracks.Add(track);
    }

    public CD WithTrack(string title, TimeSpan length)
    {
        AddTrack(new Track(Artist, title, length));
        return this;
    }
}

这是的Value~~MD~~aux对象级 - 私立制定者不允许改变这种课堂外的属性值。这里是轨道类:

This is Value Object class - private setters does not allow to change property values outside of this class. And here is class for track:

public class Track
{
    public Track(string artist, string title, TimeSpan length)
    {
        Artist = artist;
        Title = title;
        Length = length;
    }

    public string Artist { get; set; }
    public string Title { get; private set; }
    public TimeSpan Length { get; private set; }
}

现在你可以使用的Fluent API 来制作CD的集合:

Now you can use Fluent API to create collection of CDs:

List<CD> cds = new List<CD>
    {
        new CD("Awake", "Dream Theater")
            .WithTrack("6:00", new TimeSpan(00, 05, 31))
            .WithTrack("Caught in a Web", new TimeSpan(00, 05, 28))
            .WithTrack("Innocence Faded", new TimeSpan(00, 05, 34)),
        new CD("Second cd", "TestArtist")
            .WithTrack("TrackForSecond", new TimeSpan(00, 13, 37))
    };

这是XML创建:

var xDoc = new XDocument(
    new XDeclaration("1.0", "utf-8", "yes"),
    new XElement("cds",
          from cd in cds
          orderby cd.Artist
          select new XElement("cd",
               new XAttribute("artist", cd.Artist),
               new XAttribute("name", cd.Title),
               from t in cd.Tracks
               select new XElement("track",
                     new XElement("artist", t.Artist),
                     new XElement("title", t.Title),
                     new XElement("length", t.Length)));

您在这里有几个问题 - 缺少根节点,并列举了所有CD上的每一次迭代

You had several problems here - missing root node, and enumerating over all CDs on each iteration.

这篇关于LINQ到XML - 如何使用的XDocument的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆