使用Linq编写XML:状态Document中的Token EndDocument会导致XML文档无效

时间:2016-01-24 02:11:37

标签: c# linq-to-xml

[看起来比实际更多]

我正在尝试编写一个小型C#程序,通过IMAP下载邮件帐户的邮件。我有一个带有电子邮件对象的List和一个方法,该方法应该返回一个填充了List中数据的有效XDocument。 XML应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Folder ID="0" name="INBOX">
    <Mail UID="328" fromAddress="serious.business@server.com" fromDisplayName="Business guy" toAddress="me@server.com" toDisplayName="David Onter">
        <Priority>High</Priority>
        <Subject>Important info!</Subject>
        <Content>The Content goes in here.</Content>
        <AttachmentPath>/Attachments/important_document.pdf</AttachmentPath>
    </Mail>
    <Mail UID="329" fromAddress="coolkid@server.com" fromDisplayName="The cool kid" toAddress="me@server.com" toDisplayName="David Onter">
        <Priority>Normal</Priority>
        <Subject>Waaazuuuuup</Subject>
        <Content>Stay fly and snazzy</Content>
        <AttachmentPath></AttachmentPath>
    </Mail>
</Folder>
<Folder ID="1" name="Archive">
    <Mail UID="420" fromAddress="dude@server.com" fromDisplayName="Classmate8" toAddress="me@server.com" toDisplayName="David Onter">
        <Priority>Normal</Priority>
        <Subject>Maths homework</Subject>
        <Content>What was maths hw?</Content>
        <AttachmentPath></AttachmentPath>
    </Mail>
</Folder>

这是它抛出的错误:

System.InvalidOperationException: Token EndDocument in state Document would result in an invalid XML document.
at System.Xml.XmlWellFormedWriter.ThrowInvalidStateTransition(Token token, State currentState)
at System.Xml.XmlWellFormedWriter.AdvanceState(Token token)
at System.Xml.XmlWellFormedWriter.WriteEndDocument()
at System.Xml.Linq.XDocument.WriteTo(XmlWriter writer)
at System.Xml.Linq.XDocument.Save(String fileName, SaveOptions options)
at System.Xml.Linq.XDocument.Save(String fileName)
at DownTheMail.Program.Main(String[] args)
// Export to xml
XDocument xmlDoc = MailToXML(emailList);
xmlDoc.Save(@"C:\Users\David\Documents\file.xml");

这是实际的方法:

private static XDocument MailToXML(List<Email> emailList) {
    XDocument xmlDoc = new XDocument(new XDeclaration("1.0", "UTF-16", "yes"));
    // Compiler food, will be overwritten.
    XElement folder = new XElement("Folder");

    for(int i=0; i<emailList.Count; i++) {
        if(i!=0&&emailList[i-1].FolderId==emailList[i].FolderId) {
            // Write Mail and add it to the current folder
            folder.Add(new XElement("Mail", new XAttribute("UID", emailList[i].Uid),
                                            new XAttribute("fromAddress", emailList[i].FromAddress),
                                            new XAttribute("fromDisplayName", emailList[i].FromDisplayName),
                                            new XAttribute("ToAddresses", emailList[i].ToAddresses),
                                            new XAttribute("ToDisplayNames", emailList[i].ToDisplayNames),
                                                new XElement("Importance", emailList[i].Importance),
                                                new XElement("Subject", emailList[i].Subject),
                                                new XElement("BodyText", emailList[i].BodyText),
                                                new XElement("AttachmentPath", emailList[i].AttachmentPath)));
        } else {
            if(i!=0) {
                // Add current, finished folder to the document
                xmlDoc.Add(folder);
            }
            // Create new folder
            folder = new XElement("Folder", new XAttribute("id", emailList[i].FolderId),
                                            new XAttribute("name", emailList[i].FolderName));

            // Write Mail and add it to the newly created folder as the first element
            folder.Add(new XElement("Mail", new XAttribute("UID", emailList[i].Uid),
                                            new XAttribute("fromAddress", emailList[i].FromAddress),
                                            new XAttribute("fromDisplayName", emailList[i].FromDisplayName),
                                            new XAttribute("ToAddresses", emailList[i].ToAddresses),
                                            new XAttribute("ToDisplayNames", emailList[i].ToDisplayNames),
                                                new XElement("Importance", emailList[i].Importance),
                                                new XElement("Subject", emailList[i].Subject),
                                                new XElement("BodyText", emailList[i].BodyText),
                                                new XElement("AttachmentPath", emailList[i].AttachmentPath)));
        }
    }

    return xmlDoc;
}

2 个答案:

答案 0 :(得分:1)

结果XML肯定无效,因为xml只允许一个根元素。实际上,XDocument类公开了类型为XElement的“Root”属性。您可以将“文件夹”添加到此“Root”元素而不是直接添加到XDocument。

您也可以使用简单的xml字符串初始化XDocument,而不是使用XDeclaration。

答案 1 :(得分:1)

您缺少XML中的Root元素。您提供的XML无效。对于例如将根元素添加到后续XML将使其有效。 XML文档必须包含一个根元素,该元素是所有其他元素的父元素:来自wikipedia

  

每个XML文档只有一个根元素。它包含了所有   其他元素,因此是所有的唯一的父元素   其他元素。 ROOT元素也称为PARENT元素。

INSERT INTO bar (rec_id, x,y,z) VALUES (xyz, 1,2,3) ON DUPLICATE KEY count=count+1