使用 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;
}
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。