Slightly non-trivial data structure: is XmlSerializer right for me?
I'm currently using XmlSerializer
to, surprisingly enough :), handle de/serialization of my data structures - I find it wonderfully simple to use, but at the cost of flexibility. At the moment, I'm using it for a tree-based structure; since XmlSerializer
d开发者_如何学Pythonoesn't handle cyclic structures, I've added [XmlIgnore]
to my Parent
property, and do a post-deserialization iteration over the tree to fix up node parents.
Is there a better way to handle this using XmlSerializer
, or would it be better to rewrite the code using XmlReader/XmlWriter
? I suppose implementing IXmlSerializable
would work, but it seems like a fair amount of work, while still retaining the cons of XmlSerializer
.
The current post-deserialization step is OK, but I'm adding a data structure that has to be serialized to a separate XML file: basically a flat list of items that need a Parent property referencing a node from the previous tree structure. This would require yet a post-deserialization step, as well as keeping both a Parent attribute as well as as ParentId (or some trickery) in the new data structure.
So, any smart (and non-fragile) ideas? Or XmlReader/XmlWriter
it is?
Solution
DataContractSerializer
turned out to be a pretty decent solution, with pretty much the same simplicity as XmlSerializer. I opted not to use the automatic cycle handling but instead defining and OnDeserialized decorated method to handle setting the parent node; that way, the generated XML is standard-conforming.
One thing that confused me for a while was that I got crashes on some properties after deserializing, with the backing members set to null - couldn't figure out how this was possible since the backing members were definitely initialized in all possible constructors. Debugging showed constructors were never called, and after some googling I found this SO post with an explanation.
You could try binary serialization (BinarySerializer or DataContractSerializer), which I think handles cyclic graphs somewhat better, at the cost of not having a human-readable representation of the data. Alternatively, you can try the SoapFormatter as detailed here.
Use DataContractSerializer
. Mark your classes with [DataContract(IsReference = true)]
.
精彩评论