2013-12-19 51 views
2

我試圖反序列化一個xml字符串,但出於某種原因,我得到了標題中指出的錯誤。XmlException:文檔元素沒有出現 - 第1行,位置1

這是我從反序列化的代碼:

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

你可以從註釋行我甚至嘗試剝離出白色空間看,但沒有eather工作。

這是調用在我的代碼recieveObject功能:

recieveObject<Player>(ref player); 

,這裏是我的播放器類:

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

最後我tryng使用反序列化到XML玩家對象:

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

有人能告訴我爲什麼我在標題中出現錯誤嗎?

謝謝你的時間。

+1

看來您收到數據通過UDP通道。請注意,接收超過0個字節並不一定意味着數據是完整的。它可能是無效的XML。否則,我同意阿德里亞諾的回答。 –

回答

4

你從內存流的末尾寫着:

MemoryStream rms = new MemoryStream(1024); 
rms.Write (...); 

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

只需將光標移動回你開始之前反序列化:

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

最後只是兩個小建議。不要忘了處理所有可支配的對象:

MemoryStream rms = new MemoryStream(1024); 
{ 
} 

而且你不需要讀取流的字節轉換爲字符串(解碼UTF8)然後讓後面的字節(從UTF8),這種雙轉換添加任何內容(此外請注意您編碼兩次,因爲你叫GetBytes()兩次):

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

進行日誌記錄,你可以寫這樣的功能(UTF8轉換將完成僅在必要時):

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

你的記錄將被(它會只有DEBUG符號被定義調用):

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

這只是一個更漂亮的替代品:

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

甚至沒有必要寫入流中,甚至首先使用流。字節數組可以被內存流包裝。一個'StringReader'可以用來代替。等等。 –

+0

@JeffMercado是的,我在長時間的編輯中指出_improvements_。 –

+0

非常感謝!我一直在這個錯誤爲3小時大聲笑。簡直不敢相信我沒有考慮過溪流翻轉,哈哈。 – CyanPrime

相關問題