使用 Linq: Token EndDocument 在状态“文档”中编写 XML 将导致无效的 XML 文档

本文关键字:XML 文档 无效 Token Linq EndDocument 状态 使用 | 更新日期: 2023-09-27 18:31:33

[看起来比实际更多]

我正在尝试编写一个小型 C# 程序,该程序通过 IMAP 下载邮件帐户的邮件。我有一个包含电子邮件对象的列表和一个方法,该方法应返回使用列表中的数据填充的有效 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;
}

使用 Linq: Token EndDocument 在状态“文档”中编写 XML 将导致无效的 XML 文档

XML 中缺少 Root 元素。您提供的 XML 无效。例如,将根元素添加到以下XML将使其有效。XML 文档必须包含一个根元素,该根元素是所有其他元素的父元素:来自维基百科。

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

<?xml version="1.0" encoding="UTF-8"?> <root> <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> </root>

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

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