C# XML文档中出现错误。意外的XML声明。XML声明必须是文档中的第一个节点

C# XML文档中出现错误。意外的XML声明。XML声明必须是文档中的第一个节点,c#,xml,c#-4.0,serialization,C#,Xml,C# 4.0,Serialization,XML文档(8,20)中有一个错误。内部1:意外的XML声明。XML声明必须是文档中的第一个节点,并且前面不允许出现空白字符 好的,我理解这个错误 然而,让我困惑的是我是如何得到它的 我使用Microsoft的序列化工具创建文档。然后,我转过身,再次尝试使用Microsoft的反序列化工具将其读回 我无法控制以正确的格式编写XML文件——我可以看到 下面是我用来读写的一个例程 private string xmlPath = System.Web.Hosting.HostingEnvironme

XML文档(8,20)中有一个错误。内部1:意外的XML声明。XML声明必须是文档中的第一个节点,并且前面不允许出现空白字符

好的,我理解这个错误

然而,让我困惑的是我是如何得到它的

我使用Microsoft的序列化工具创建文档。然后,我转过身,再次尝试使用Microsoft的反序列化工具将其读回

我无法控制以正确的格式编写XML文件——我可以看到

下面是我用来读写的一个例程

private string xmlPath = System.Web.Hosting.HostingEnvironment.MapPath(WebConfigurationManager.AppSettings["DATA_XML"]);
private object objLock = new Object();
public string ErrorMessage { get; set; }

public StoredMsgs Operation(string from, string message, FileAccess access) {
    StoredMsgs list = null;
    lock (objLock) {
        ErrorMessage = null;
        try {
            if (!File.Exists(xmlPath)) {
                var root = new XmlRootAttribute(rootName);
                var serializer = new XmlSerializer(typeof(StoredMsgs), root);
                if (String.IsNullOrEmpty(message)) {
                    from = "Code Window";
                    message = "Created File";
                }
                var item = new StoredMsg() {
                    From = from,
                    Date = DateTime.Now.ToString("s"),
                    Message = message
                };
                using (var stream = File.Create(xmlPath)) {
                    list = new StoredMsgs();
                    list.Add(item);
                    serializer.Serialize(stream, list);
                }
            } else {
                var root = new XmlRootAttribute("MessageHistory");
                var serializer = new XmlSerializer(typeof(StoredMsgs), root);
                var item = new StoredMsg() {
                    From = from,
                    Date = DateTime.Now.ToString("s"),
                    Message = message
                };
                using (var stream = File.Open(xmlPath, FileMode.Open, FileAccess.ReadWrite)) {
                    list = (StoredMsgs)serializer.Deserialize(stream);
                    if ((access == FileAccess.ReadWrite) || (access == FileAccess.Write)) {
                        list.Add(item);
                        serializer.Serialize(stream, list);
                    }
                }
            }
        } catch (Exception error) {
            var sb = new StringBuilder();
            int index = 0;
            sb.AppendLine(String.Format("Top Level Error: <b>{0}</b>", error.Message));
            var err = error.InnerException;
            while (err != null) {
                index++;
                sb.AppendLine(String.Format("\tInner {0}: {1}", index, err.Message));
                err = err.InnerException;
            }
            ErrorMessage = sb.ToString();
        }
    }
    return list;
}
private string xmlPath=System.Web.Hosting.HostingEnvironment.MapPath(WebConfigurationManager.AppSettings[“DATA_XML]”);
私有对象objLock=新对象();
公共字符串错误消息{get;set;}
public StoredMsgs操作(字符串来源、字符串消息、文件访问){
StoredMsgs list=null;
锁(objLock){
ErrorMessage=null;
试一试{
如果(!File.Exists(xmlPath)){
var root=新的XmlRootAttribute(rootName);
var serializer=newxmlserializer(typeof(StoredMsgs),root);
if(String.IsNullOrEmpty(message)){
from=“代码窗口”;
message=“已创建文件”;
}
var item=newstoredmsg(){
From=From,
Date=DateTime.Now.ToString(“s”),
消息=消息
};
使用(var stream=File.Create(xmlPath)){
list=新的StoredMsgs();
列表。添加(项目);
序列化(流,列表);
}
}否则{
var root=新的XmlRootAttribute(“MessageHistory”);
var serializer=newxmlserializer(typeof(StoredMsgs),root);
var item=newstoredmsg(){
From=From,
Date=DateTime.Now.ToString(“s”),
消息=消息
};
使用(var stream=File.Open(xmlPath,FileMode.Open,FileAccess.ReadWrite)){
list=(StoredMsgs)序列化程序。反序列化(流);
if((access==FileAccess.ReadWrite)| |(access==FileAccess.Write)){
列表。添加(项目);
序列化(流,列表);
}
}
}
}捕获(异常错误){
var sb=新的StringBuilder();
int指数=0;
AppendLine(String.Format(“顶层错误:{0}”,Error.Message));
var err=error.InnerException;
while(err!=null){
索引++;
sb.AppendLine(String.Format(“\tInner{0}:{1}”,index,err.Message));
err=err.InnerException;
}
ErrorMessage=sb.ToString();
}
}
退货清单;
}
我的日常工作有什么问题吗?如果微软写了这个文件,在我看来,它应该能够读回它

它应该足够通用,任何人都可以使用

这是我的StoredMsg类:

[Serializable()]
[XmlType("StoredMessage")]
public class StoredMessage {
    public StoredMessage() {
    }
    [XmlElement("From")]
    public string From { get; set; }
    [XmlElement("Date")]
    public string Date { get; set; }
    [XmlElement("Message")]
    public string Message { get; set; }
}

[Serializable()]
[XmlRoot("MessageHistory")]
public class MessageHistory : List<StoredMessage> {
}
[Serializable()]
[XmlType(“StoredMessage”)]
公共类存储消息{
公共存储消息(){
}
[XmlElement(“From”)]
来自{get;set;}的公共字符串
[XmlElement(“日期”)]
公共字符串日期{get;set;}
[XmlElement(“消息”)]
公共字符串消息{get;set;}
}
[可序列化()]
[XmlRoot(“MessageHistory”)]
公共类MessageHistory:列表{
}
它生成的文件在我看来没有任何问题

我在这里看到了解决方案:

但是,在这种情况下,似乎有人已经有了想要阅读的XML文档。他们只需要修好它


我在Microsoft中创建了一个XML文档,因此Microsoft应该将其读回。

问题是您正在向该文件添加内容。您可以反序列化,然后重新序列化到同一个流,而无需倒带并将大小调整为零。这将为您提供多个:

使用以下改编自的扩展方法:

公共部分类XmlSerializerHelper
{
公共静态列表ReadObjects(Stream-Stream,bool-closeInput=true,XmlSerializer-serializer=null)
{
var list=新列表();
serializer=序列化程序??新的XmlSerializer(typeof(T));
var设置=新的XmlReaderSettings
{
ConformanceLevel=ConformanceLevel.Fragment,
CloseInput=CloseInput,
};
使用(var xmlTextReader=XmlReader.Create(流,设置))
{
while(xmlTextReader.Read())
{//跳过空格
if(xmlTextReader.NodeType==XmlNodeType.Element)
{
使用(var subReader=xmlTextReader.ReadSubtree())
{
var logEvent=(T)序列化程序。反序列化(子读取器);
列表。添加(日志事件);
}
}
}
}
退货清单;
}    
}
请注意,如果要使用自定义
XmlRootAttribute
创建
XmlSerializer
,则必须


示例。

XML文档最多可以有一个声明(在开始时),最多可以有一个根元素。问题是您正在向文件中添加。您可以反序列化,然后重新序列化到同一个流,而无需倒带并将大小调整为零。这将为您提供多个,这是XML标准所不允许的。有关处理具有多个根元素的文档的方法,请参见此处:您也需要这样做。我一直在查看该链接示例。有什么我遗漏的吗?是什么将结束的XML片段写入根节点?序列化不写入关闭的根节点吗?它
<?xml version="1.0"?>
<StoredMessage>
</StoredMessage
<?xml version="1.0"?>
<StoredMessage>
</StoredMessage
private string xmlPath = System.Web.Hosting.HostingEnvironment.MapPath(WebConfigurationManager.AppSettings["DATA_XML"]);
private object objLock = new Object();
public string ErrorMessage { get; set; }

const string rootName = "MessageHistory";
static readonly XmlSerializer serializer = new XmlSerializer(typeof(StoredMessage), new XmlRootAttribute(rootName));

public MessageHistory Operation(string from, string message, FileAccess access)
{
    var list = new MessageHistory();
    lock (objLock)
    {
        ErrorMessage = null;
        try
        {
            using (var file = File.Open(xmlPath, FileMode.OpenOrCreate))
            {
                list.AddRange(XmlSerializerHelper.ReadObjects<StoredMessage>(file, false, serializer));
                if (list.Count == 0 && String.IsNullOrEmpty(message))
                {
                    from = "Code Window";
                    message = "Created File";
                }
                var item = new StoredMessage()
                {
                    From = from,
                    Date = DateTime.Now.ToString("s"),
                    Message = message
                };
                if ((access == FileAccess.ReadWrite) || (access == FileAccess.Write))
                {
                    file.Seek(0, SeekOrigin.End);
                    var writerSettings = new XmlWriterSettings
                    {
                        OmitXmlDeclaration = true,
                        Indent = true, // Optional; remove if compact XML is desired.
                    };
                    using (var textWriter = new StreamWriter(file))
                    {
                        if (list.Count > 0)
                            textWriter.WriteLine();
                        using (var xmlWriter = XmlWriter.Create(textWriter, writerSettings))
                        {
                            serializer.Serialize(xmlWriter, item);
                        }
                    }
                }
                list.Add(item);
            }
        }
        catch (Exception error)
        {
            var sb = new StringBuilder();
            int index = 0;
            sb.AppendLine(String.Format("Top Level Error: <b>{0}</b>", error.Message));
            var err = error.InnerException;
            while (err != null)
            {
                index++;
                sb.AppendLine(String.Format("\tInner {0}: {1}", index, err.Message));
                err = err.InnerException;
            }
            ErrorMessage = sb.ToString();
        }
    }
    return list;
}
public partial class XmlSerializerHelper
{
    public static List<T> ReadObjects<T>(Stream stream, bool closeInput = true, XmlSerializer serializer = null)
    {
        var list = new List<T>();

        serializer = serializer ?? new XmlSerializer(typeof(T));
        var settings = new XmlReaderSettings
        {
            ConformanceLevel = ConformanceLevel.Fragment,
            CloseInput = closeInput,
        };
        using (var xmlTextReader = XmlReader.Create(stream, settings))
        {
            while (xmlTextReader.Read())
            {   // Skip whitespace
                if (xmlTextReader.NodeType == XmlNodeType.Element)
                {
                    using (var subReader = xmlTextReader.ReadSubtree())
                    {
                        var logEvent = (T)serializer.Deserialize(subReader);
                        list.Add(logEvent);
                    }
                }
            }
        }

        return list;
    }    
}