2013-12-19 5 views
2

XML 문자열을 deserialize하려면 tring 해요,하지만 어떤 이유로 제목에 명시된 오류가 나타납니다.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<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을

내 코드에서 recieveObject 함수에 대한 호출입니다 선수 개체 : 내가 제목에 오류를 받고 있어요 왜

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

누군가가 말해 주시겠습니까?

감사합니다.

+1

당신이 받고있는 것 같다 데이터는 UDP 채널을 통해 전송됩니다. 0 바이트보다 많이 수신한다고해서 반드시 데이터가 완료되었다는 의미는 아닙니다. 잘못된 XML 일 수 있습니다. 그렇지 않으면 나는 Adriano의 대답에 동의한다. –

답변

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 

마지막 두 작은 제안. 모든 일회용 개체를 처리하는 것을 잊지 마십시오 : 다시 (UTF8)에서

또한
MemoryStream rms = new MemoryStream(1024); 
{ 
} 

당신이 문자열 (디코딩 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 시간 동안처럼이 실수를 해왔다. LOL이 뒤집히는 것에 대해 생각하지 않았다는 것을 믿을 수 없습니다. – CyanPrime