Title: protocol buffer message to and from an XPathDocument
Tags: c#;.net;xml;protocol-buffers;protobuf-net
Question: 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?

I am using protobuf-net and my source code for reproducing it looks like this:

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&gt;();

            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&gt;();

            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&gt;(memoryStream);
                }
            }
            return t;
        }
    }
}
```



I tried to extend use Serializer.Merge but the Test object is empty when it comes back from xml.

```    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&gt;();

            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&gt;(SerializeStream);
            Test ObjectExist = new Test();

            if (ObjectExist == null)
            {
                return NewObject;
            }
            else
            {
                SerializeStream.Seek(0, SeekOrigin.Begin);
                Serializer.Merge<Test&gt;(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 version="1.0" encoding="utf-8"?&gt;
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  <a&gt;
    <A&gt;
      <str&gt;test</str&gt;
    </A&gt;
  </a&gt;
</Test&gt;
```



Here is another answer: The only time you use protobuf here is:

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

where you have written xml (```x``` is an ```XmlSerializer```), and then attempted to read it via protobuf (```Serializer.Deserialize```).

However; protobuf is not xml; it is a binary format completely unrelated to xml. If your intention is to deep-clone the data, you should also serialize with protobuf-net (```Serializer.Serialize```).

It is often possible to convert a model between the two formats, but the streams themselves are not swappable.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2011:00:06/24/11', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<c#><.net><xml><protocol-buffers><protobuf-net>', 'Title': 'protocol buffer message to and from an XPathDocument', 'ViewCount': 745, 'id': 6467758, 'user_AboutMe': '<p>I love &quot;C with Classes&quot; as in C++</p>\n', 'user_AccountId': 111525.0, 'user_DisplayName': 'Damian', 'user_Reputation': 4257.0, 'user_Views': 668.0, 'user_id': 294569.0}}