I have a situation where I have an xml file that I don't want to modify. The AddAnnotation function in XElement class provides an option to add memory-only data which is not serialized and not part of the XML.
I want to be able to save these annotations (for example: to another xml file) and then to deserialize both the xml and the annotations in order to get the same object I had.
I don't want to change the original xml and that's the reason that I use annotations.
To summarize, I want to be able to add custom data to an xml file. This data won't be a part of the xml when I serialize it or it will be a part of the xml but I would be able to retrieve the original xml easily.
Do you have any recommendation how I can do such a thing?
Edit: Should I use xml processing instructions? Are processing instructions intended for this kind of usage?
It sounds to me like the simplest approach would be to use regular nodes, but in a different xml namespace - i.e.
(where
myData
is anxmlns
alias for the namespace-uri)In many cases, readers are only checking for data in their namespace (or the default/blank namespace) - values in custom namespaces are generally skipped.
To get pack the original xml, one simple approach would be to run it through an xslt that only respects the default/original namespace.
To remove such data from an
XElement
, perhaps:The original question used the word "Serialize" but then also mentioned XElement and annotation. To me these are two different things.
If you really want to use the XmlSerializer:
What I would do is use XmlAttributeOverrides, to differentiate the serialization. With the XmlAttributeOverrides you can programmatically, at runtime, override the xml serialization attributes that decorate your types.
Within your type, you can have a field/property that is intended to hold the annotation/documentation. Decorate that with XmlIgnore. Then, create one instance of the XmlSerializer that accepts no overrides. The annotation will not be serialized or de-serialized. Create another instance of the XmlSerializer for that type, using an XmlAttributeOverrides object. Specify an override for the XmlIgnore'd property (use XmlElementAttribute), as well as overrides for any attributes on any of the other members (use XmlIgnore=true).
Serialize the instance twice, one with each serializer.
Edit: here's the code:
output, using the in-line attributes:
output, using the override attributes: