C# XML文档中出现错误。意外的XML声明。XML声明必须是文档中的第一个节点
XML文档(8,20)中有一个错误。内部1:意外的XML声明。XML声明必须是文档中的第一个节点,并且前面不允许出现空白字符 好的,我理解这个错误 然而,让我困惑的是我是如何得到它的 我使用Microsoft的序列化工具创建文档。然后,我转过身,再次尝试使用Microsoft的反序列化工具将其读回 我无法控制以正确的格式编写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
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;
}
}