[英]protocol buffer message to and from an XPathDocument
I am trying to serialize and deserialize a protocol buffer message to and from an XPathDocument but it fails with an exception: ProtoBuf.ProtoException: Mismatched group tags detected in message How do I make this work? 我正在尝试对XPathDocument上的协议缓冲区消息进行序列化和反序列化,但是它失败,并出现以下异常: ProtoBuf.ProtoException:消息中检测到不匹配的组标签如何使这项工作?
I am using protobuf-net and my source code for reproducing it looks like this: 我正在使用protobuf-net,我的源代码用于复制它,如下所示:
TestMsg.proto 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;
}
}
}
I tried to extend use Serializer.Merge but the Test object is empty when it comes back from xml. 我尝试扩展使用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();
}
}
}
}
The xml file I dump out looks like this 我转储的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>
The only time you use protobuf here is: 您在这里唯一使用protobuf是:
x.Serialize(w, xmlDoc);
memoryStream.Position = 0;
t = Serializer.Deserialize<Test>(memoryStream);
where you have written xml ( x
is an XmlSerializer
), and then attempted to read it via protobuf ( Serializer.Deserialize
). 您已在其中编写xml( x
是XmlSerializer
),然后尝试通过protobuf( Serializer.Deserialize
)读取它的位置。
However; 然而; protobuf is not xml; protobuf不是xml; it is a binary format completely unrelated to xml. 它是一种完全与xml不相关的二进制格式。 If your intention is to deep-clone the data, you should also serialize with protobuf-net ( Serializer.Serialize
). 如果你的意图是深克隆的数据,你也应该序列与protobuf网( Serializer.Serialize
)。
It is often possible to convert a model between the two formats, but the streams themselves are not swappable. 它往往是可能的模型转换两种格式之间,但流本身不支持热插拔。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.