The way to obtain relationship information of XmlNode is updated to post. Though it gives a good result, it's a little bit slow.
protobuf-net deserialized XElement return null as NextNode
-
29-06-2022 - |
Question
version : protobuf-net r282
Serialize XElement object and deserialize it will result lost of relationship information such like NextNode, Parent... It looks like that only Xml data in it is stored.
Is there any way to store relationship information?
Thanks!
Here is a class I have used to test:
[ProtoContract]
public class Person
{
[ProtoMember(1)]
public string FirstName { get; set; }
[ProtoMember(2)]
public string FamilyName { get; set; }
[ProtoMember(3)]
public int Age { get; set; }
[ProtoMember(4)]
public XDocument Details { get; set; }
[ProtoMember(5)]
public XElement Business { get; set; }
// ctor
public Person() { } // ctor for Deserialize
public Person(string first, string family, int age, XDocument details)
{
FirstName = first;
FamilyName = family;
Age = age;
Details = details;
Business = Details == null ? null : Details.Descendants("business").FirstOrDefault();
}
// calculated properties
public string FullName { get { return FirstName + " " + FamilyName; } }
// Methods
public string GetDetails(string key)
{
if (this.Details == null) return null;
var found = (from n in Details.Descendants(key)
select n.Value).FirstOrDefault();
return found;
}
}
[Update]
One way to avoid the problem is serialize absolute path of xelement instead of itself. Here is a sample.
using System.Xml.XPath;
.....
//[ProtoMember(5)]
public XElement Business { get; set; }
[ProtoMember(5)]
public string BusinessSerialized
{
get { return Business == null ? null : Business.GetAbsoluteXPath(); }
set
{
if (value == null) { Business = null; }
else
{
Business = Details.XPathSelectElements(value).FirstOrDefault();
}
}
}
GetAbsoluteXPath is a extension method for XElement. I have found it in this question.
Solution 2
OTHER TIPS
Wow, I wouldn't even have expected that XElement
worked at all - I guess it is finding the .ToString()
/ .Parse()
pair, and using those.
This simply isn't a use-case that protobuf-net targets. And I certainly wouldn't expect it to retain data outside of the immediate leaf/node that is being represented in the data (that would basically mean that it had to serialize an entire XDocument
/ whatever every time it saw any element - via the .Document
property.
Your workaround with storing the absolute xpath is a reasonable one; that is very different to storing an XElement
.