XmlException: Document element did not appear - line 1, position 1

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

I'm tring to deserialize a xml string, but for some reason I'm getting the error stated in the title.

This is the code I'm deserializing from:

public void recieveObject<T>(ref T t){         XmlSerializer xs = new XmlSerializer(typeof(T));         Debug.Log("Waiting for client");         byte[] recievedData = udpc.Receive(ref recieveFromEndPoint);          if(recievedData.Length > 0){             string xmlStr = System.Text.Encoding.UTF8.GetString(recievedData, 0, recievedData.Length);             //xmlStr = xmlStr.Replace("\r","").Replace("\n", "").Replace("\t","").Replace(" ", "");             Debug.Log(xmlStr);              MemoryStream rms = new MemoryStream(1024);             rms.Write (System.Text.Encoding.UTF8.GetBytes(xmlStr), 0, System.Text.Encoding.UTF8.GetBytes(xmlStr).Length);             Debug.Log ("ms: " + System.Text.Encoding.UTF8.GetString(rms.ToArray()));             t = (T) xs.Deserialize(rms);         }     } 

As you can see from the commented line I even tried stripping out the white space, but that didn't work eather.

This is the call to the recieveObject function in my code:

recieveObject<Player>(ref player); 

And here is my Player class:

using UnityEngine; using System.Collections; using System.Xml.Serialization;  [XmlRoot("player")] public class Player{     [XmlElement("x")]     public int x;      [XmlElement("y")]     public int y;      [XmlElement("name")]     public string name;      private int maxNameLength = 12;      public Player(){}     public Player(int x, int y, string name){         this.x = x;         this.y = y;         if(name.Length > maxNameLength) name = name.Substring(0, maxNameLength);         this.name = name;     } } 

and finally the Xml I'm tryng to use to deserialize into a player object:

<player>   <x>50</x>   <y>100</y>   <name>Tester</name> </player> 

Can someone please tell me why I'm getting the error in the title?

Thank you for your time.

回答1:

You're reading from end of memory stream:

MemoryStream rms = new MemoryStream(1024); rms.Write (...);  // Now cursor is at end of file, nothing to read here t = (T) xs.Deserialize(rms); 

Just move cursor back to beginning before you deserialize:

rms.Seek(0, SeekOrigin.Begin); t = (T) xs.Deserialize(rms); // Now deserializer has data to read 

Finally just two small suggestions. Don't forget to dispose all disposable objects:

MemoryStream rms = new MemoryStream(1024); { } 

Also you don't need to read a byte of stream into a string (decoding UTF8) then getting bytes back (from UTF8), this double conversion adds nothing (moreover please note you encode twice because you call GetBytes() twice):

if (recievedData.Length > 0)  {     using (MemoryStream rms = new MemoryStream(receivedData))     {        t = (T) xs.Deserialize(rms);     } } 

For logging purposes you can write a function like this (UTF8 conversion will be done only if necessary):

static class Logger {     [Conditional("DEBUG")]     public static void Debug(Func<string> text)     {         Debug.Log(text());     } } 

Your logging will be (and it'll be called only if DEBUG symbol is defined):

Logger.Debug(() => "ms: " + Encoding.UTF8.GetString(rms.ToArray())); 

It's just a more pretty alternative to:

#if DEBUG     Debug.Log ("ms: " + System.Text.Encoding.UTF8.GetString(rms.ToArray())); #endif 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!