c# - error in XML document. Unexpected XML declaration. XML declaration must be the first node in the document -


there error in xml document (8, 20). inner 1: unexpected xml declaration. xml declaration must first node in document, , no white space characters allowed appear before it.

ok, understand error.

how it, however, perplexes me.

i create document microsoft's serialize tool. then, turn around , attempt read back, again, using microsoft's deserialize tool.

i not in control of writing xml file in correct format - can see.

here single routine use read , write.

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)) {                     = "code window";                     message = "created file";                 }                 var item = new storedmsg() {                     = 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,                     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; } 

is wrong routine? if microsoft write file, seems me should able read back.

it should generic enough use.

here storedmsg class:

[serializable()] [xmltype("storedmessage")] public class storedmessage {     public storedmessage() {     }     [xmlelement("from")]     public string { get; set; }     [xmlelement("date")]     public string date { get; set; }     [xmlelement("message")]     public string message { get; set; } }  [serializable()] [xmlroot("messagehistory")] public class messagehistory : list<storedmessage> { } 

the file generates doesn't me has issues.

xml screenshot

i saw solution here:

error: xml declaration must first node in document

but, in case, seems had xml document wanted read. had fix it.

i have xml document created microsoft, should read in microsoft.

the problem adding file. deserialize, re-serialize same stream without rewinding , resizing zero. gives multiple root elements:

<?xml version="1.0"?> <storedmessage> </storedmessage <?xml version="1.0"?> <storedmessage> </storedmessage 

multiple root elements, , multiple xml declarations, invalid according xml standard, .net xml parser throws exception in situation default.

for possible solutions, see xml error: there multiple root elements, suggests either:

  1. enclose list of storedmessage elements in synthetic outer element, e.g. storedmessagelist.

    this require load list of messages file, add new message, , truncate file , re-serialize entire list when adding single item. performance may worse in current approach, xml valid.

  2. when deserializing file containing concatenated root elements, create xml writer using xmlreadersettings.conformancelevel = conformancelevel.fragment , iteratively walk through concatenated root node(s) , deserialize each 1 individually shown, e.g., here. using conformancelevel.fragment allows reader parse streams multiple root elements (although multiple xml declarations still cause error thrown).

    later, when adding new element end of file using xmlserializer, seek end of file , serialize using xml writer returned xmlwriter.create(textwriter, xmlwritersettings) xmlwritersettings.omitxmldeclaration = true. prevents output of multiple xml declarations explained here.

for option #2, operation following:

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))                 {                     = "code window";                     message = "created file";                 }                 var item = new storedmessage()                 {                     = 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 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; } 

using following extension method adapted read nodes of xml file in c#:

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;     }     } 

note if going create xmlserializer using custom xmlrootattribute, must cache serializer avoid memory leak.

sample fiddle.


Comments

Popular posts from this blog

java - UnknownEntityTypeException: Unable to locate persister (Hibernate 5.0) -

python - ValueError: empty vocabulary; perhaps the documents only contain stop words -

ubuntu - collect2: fatal error: ld terminated with signal 9 [Killed] -