2011-06-24 54 views
1

我試圖序列化和反序列化的協議緩衝區消息,並從XPathDocument的,但它失敗的異常: ProtoBuf.ProtoException:在消息 如何檢測不匹配的組標籤我做這個工作?協議緩衝消息,並從XPathDocument的

我使用protobuf網和再現它看起來像這樣我的源代碼:

TestMsg.proto

option optimize_for = SPEED; 

//************************* 
message Test { 
    repeated A a = 1; 
} 

message A { 
    required string str = 1; 
} 

Progam.cs

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 
using System.Xml.XPath; 
using ProtoBuf; 
using TestMsg; 

namespace protocolbufferserialize 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Test t = new Test(); 
      XPathDocument xmldoc = Serialize(t); 
      Test t1 = Serialize(xmldoc); 
     } 

     public static XPathDocument Serialize(Test wro) 
     { 
      XPathDocument xmlDoc = null; 
      Serializer.PrepareSerializer<Test>(); 

      XmlSerializer x = new XmlSerializer(wro.GetType()); 
      using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       using (TextWriter w = new StreamWriter(memoryStream)) 
       { 
        x.Serialize(w, wro); 
        memoryStream.Position = 0; 
        xmlDoc = new XPathDocument(memoryStream); 
       } 
      } 
      return xmlDoc; 
     } 

     public static Test Serialize(XPathDocument xmlDoc) 
     { 
      Test t = null; 
      Serializer.PrepareSerializer<Test>(); 

      XmlSerializer x = new XmlSerializer(xmlDoc.GetType()); 
      using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       using (TextWriter w = new StreamWriter(memoryStream)) 
       { 
        x.Serialize(w, xmlDoc); 
        memoryStream.Position = 0; 
        t = Serializer.Deserialize<Test>(memoryStream); 
       } 
      } 
      return t; 
     } 
    } 
} 

我試着擴展使用Serializer.Merge,但是當它從xml返回時Test對象是空的。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Xml; 
using System.Xml.Serialization; 
using System.Xml.XPath; 
using ProtoBuf; 
using TestMsg; 

namespace TestXMLSerilizationLars 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Test t = new Test(); 
      A a = new A(); 
      string str = "test"; 
      a.str = str; 
      t.a.Add(a); 
      XPathDocument xmldoc = Serialize(t); 
      WriteXpathDocument(xmldoc, "c:\\testmsg.xml"); 
      Test t1 = Serialize(xmldoc); 
     } 

     public static XPathDocument Serialize(Test t) 
     { 
      XPathDocument xmlDoc = null; 
      Serializer.PrepareSerializer<Test>(); 

      XmlSerializer x = new XmlSerializer(t.GetType()); 
      using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       using (TextWriter w = new StreamWriter(memoryStream)) 
       { 
        x.Serialize(w, t); 
        memoryStream.Position = 0; 
        xmlDoc = new XPathDocument(memoryStream); 
       } 
      } 
      return xmlDoc; 
     } 

     public static Test Serialize(XPathDocument xmlDoc) 
     { 
      Test t = null; 

      Type type = xmlDoc.GetType(); 

      XmlSerializer serializer = new XmlSerializer(type); 

      using (MemoryStream memoryStream = new MemoryStream()) 
      { 
       serializer.Serialize(memoryStream, xmlDoc); 
       // memoryStream.Close(); 
       Test newt = Deserialize(memoryStream.ToArray()); 
       return newt; 
      }    
      return t; 
     } 

     static public Test Deserialize(byte[] Bytes) 
     { 
      MemoryStream SerializeStream = new MemoryStream(Bytes); 
      Test NewObject = Serializer.Deserialize<Test>(SerializeStream); 
      Test ObjectExist = new Test(); 

      if (ObjectExist == null) 
      { 
       return NewObject; 
      } 
      else 
      { 
       SerializeStream.Seek(0, SeekOrigin.Begin); 
       Serializer.Merge<Test>(SerializeStream, ObjectExist); 
       return ObjectExist; 
      } 
     } 

     public static void WriteXpathDocument(XPathDocument xpathDoc, string filename) 
     { 
      // Create XpathNaviagtor instances from XpathDoc instance. 
      XPathNavigator objXPathNav = xpathDoc.CreateNavigator(); 

      // Create XmlWriter settings instance. 
      XmlWriterSettings objXmlWriterSettings = new XmlWriterSettings(); 
      objXmlWriterSettings.Indent = true; 

      // Create disposable XmlWriter and write XML to file. 
      using (XmlWriter objXmlWriter = XmlWriter.Create(filename, objXmlWriterSettings)) 
      { 
       objXPathNav.WriteSubtree(objXmlWriter); 
       objXmlWriter.Close(); 
      } 
     } 
    } 
} 

的XML文件,我倒出來像這樣

<?xml version="1.0" encoding="utf-8"?> 
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <a> 
    <A> 
     <str>test</str> 
    </A> 
    </a> 
</Test> 

回答

1

您的protobuf在這裏使用的唯一情況是:

x.Serialize(w, xmlDoc); 
memoryStream.Position = 0; 
t = Serializer.Deserialize<Test>(memoryStream); 

,你必須編寫的XML(xXmlSerializer) ,然後嘗試通過protobuf(Serializer.Deserialize)閱讀它。

但是; protobuf不是xml;它是一個二進制格式完全與xml無關。如果您的目的是深入克隆數據,您還應該使用protobuf-net(Serializer.Serialize)將序列化爲

往往可以將模型轉換兩種格式之間,但流自己不支持熱插拔。