XML Serialization, in this case, IXmlSerializable or Attributes - c#

I've done some XML serialization before but i used Attributes, I'm not sure this is doable for my next assignment, here's a brief list of XML manip requirementes.
General Purpose XMl manipulation, tied to a treeview, no schema.
Load/Save XML.
Load/Save Attributes as well as Values (i believe the term is Element Text?), and be mindful of the Node's name.
Comments can be safely ignored as can Document info markup (ie, the UTF-8 and schema tags)
Any suggestions on how best to handle this?

I probably wouldn't bother with an object model and IXmlSerializable - it sounds like you might just as well talk in terms of an XmlElement / XmlDocument - i.e. pass the data around as a block of xml. Since you have no schema it would be pointless to shred it out; you might as well do it via an xml DOM.
When you say treeview - is this winforms, asp.net, wpf? I believe the asp.net treeview can take an xml source, but for winforms you'd have to iterate the nodes yourself.

Don't know what exactly you mean with "before but i used Attributes" but I would recommend XmlSerializer too:
With "simple" classes it works usually out of the box.
Collections might need some more work, but it depends on your requirements and object structure.
There are other build in XML serializers like XAML or the WCF DataContractSerializer. All have pros and cons. But if you want to fine tune your XML format, XMLSerializer is the most flexibel one.
You can approach your format step by step: If the default looks good, your done. If not you have to add just some attributes in most cases.
If you want complete control, you can still implement IXmlSerialize to fine tune your format.
Everything applies on a per class basis: Use the default where appropriate, add some attributes where required and implement IXmlSerializable as required.

I would suggest you to use the simple XML serialization supported by the .NET framework.
Go through these MSDN documentation
How to Serialize an object
How to Deserialize an object

Related

Is it possible to have two sets of serialization attributes in a C# set of classes?

I have a set of C# classes I serialize using XmlSerializer. I have a root object with several properties that points to some subclasses. I used Attributes to control XMl serialization, like element names.
The problem is that now I need a second XML format for the same classes, without removing the first format. What i need to do is to create a "compressed" format, where the XML Element names will be smaller, but i want to keep the more verbose names for clarity. It would be a users choice.
How can I achieve that without having to create a second set of classes?
Ok, I stand corrected, you can do this. Have a look at XmlAttributeOverrides. (Thanks to the comment from #Paul Abbot)
Please note that XML is verbose because it's supposed to be compressed by an external compression algorithm. Making XML smaller by using less verbose names is more work and still not as good as using a compression library on the result. If you want your XML to be smaller, compress it.

user interface to get xml element's data in c#

I am trying develop a website which provide user interface to generate XML file. The user interface will ask for data required in various XML elements. The generate XML should follow DTD specifications.
So here is what I did.
I converted DTD to XSD.
I created C# class using xsd.exe tool.
Now my question is how can I generate dynamic input boxes on the webpage that will ask for required element data from the C# class I created.
I need some way to know the required and optional elements and their data type and attribute and all from the C# class I created.
i hope you get what i am asking, thanks for looking.
Keep in mind that most of the required/optional semantics from the xsd are lost in the classes generated with xsd.exe. You basically have 2 (+1 edited later ) options:
Use reflection over your generated types to render UI elements for each property. You'll have to manually manage/define databindings
Drop the xsd.exe classes and generate your UI elements by traversing the xsd itself. That way you get way more info about optional/nullable elements, cardinality etc. Construct your resulting xml by hand (use XDocument) from your UI inputs.
The hybrid approach: Reflect over generated classes for structure (easier traversal logic. no need to handle external includes etc). Go to the xsd for the additional info (You'll need to somehow figure out where in the xsd to find your needed definitions that map to the current property)
Either way you choose this will not be a trivial task and you'll need a lot of work to make it happen. And if we're going in the realm of XSD choice elements etc. you'll soon figure out that no straight forward UI can cover all the possible scenarios

Update existing XML file via serialization

I am using xml serialization and de-serialization to read and write to an XML file. Everything is working and I love it because I can access any data from the file via the single object that I generated.
However, I have to update certain element or remove it from my xml file. From reading around the site I think I can do this with Xpath or LINQ but I still like to do it via serialization due to the above reason. Is it possible? Does serialization mean to do this kind of logic? oh and I don't want to delete/recreate my file because it defeats the purpose of updating.
Changing it in the xml can be iffy, removing a node unless it's one of a collection, will almost certainly break it, and possibly even then. You might be able to get this to work but it will make your code extremely fragile, and could leave you with some horrendously difficult bugs.
Deserialise it. Change the property and serialise it again.
Or don't use serialisation to get your xml.

Serialization for document storage

I write a desktop application that can open / edit / save documents.
Those documents are described by several objects of different types that store references to each other. Of course there is a Document class that that serves as the root of this data structure.
The question is how to save this document model into a file.
What I need:
Support for recursive structures.
It must be able to open files even if they were produced from slightly different classes. My users don't want to recreate every document after every release just because I added a field somewhere.
It must deal with classes that are not known at compile time (for plug-in support).
What I tired so far:
XmlSerializer -> Fails the first and last criteria.
BinarySerializer -> Fails the second criteria.
DataContractSerializer: Similar to XmlSerializer but with support for cyclic (recursive) references. Also it was designed with (forward/backward) compatibility in mind: Data Contract Versioning. [edit]
NetDataContractSerializer: While the DataContractSerializer still requires to know all types in advance (i.e. it can't work very well with inheritance), NetDataContractSerializer stores type information in the output. Other than that the two seem to be equivalent. [edit]
protobuf-net: Didn't have time to experiment with it yet, but it seems similar in function to DataContractSerializer, but using a binary format. [edit]
Handling of unknown types [edit]
There seem two be two philosophies about what to do when the static and dynamic type differ (if you have a field of type object but a, lets say, Person-object in it). Basically the dynamic type must somehow get stored in the file.
Use different XML tags for different dynamic types. But since the XML tag to be used for a particular class might not be equal to the class name, its only possible to go this route if the deserializer knows all possible types in advance (so that he can scan them for attributes).
Store the CLR type (class name, assembly name & version) during serialization. Use this info during deserialization to instantiate the right class. The types must not be known prior to deserialization.
The second one is simpler to use, but the resulting file will be CLR dependent (and less sensitive to code modifications). Thats probably why XmlSerializer and DataContractSerializer choose the first way. NetDataContractSerializer is not recomended because its using the second approch (So does BinarySerializer by the way).
Any ideas?
The one you haven't tried is DataContractSerializer. There is a constructor that takes a parameter bool preserveObjectReferences that should handle the first criteria.
The WCF data contract serializer is probably closest to your needs, although not perfect.
There is only limited support for backwards compatibility (i.e. whether old versions of the program can read documents generated with a newer version). New fields are supported (via IExtensibleDataObject), but new classes or new enum values not.
I would think the XmlSerializer is your best bet. You won't be able to support everything on your requirements list without a bit of work in your Document classes - but the XmlSerializer architecture gives you extensibility points which should allow you to tap into its mechanism deep enough to do just about anything.
Using the IXmlSerializable interface - by implementing that on your classes you want to store - you should be able to do just about anything, really.
The interface exposes basically two methods - ReadXml And WriteXml
public void WriteXml (XmlWriter writer)
{
// do what you need to do to write out your XML for this object
}
public void ReadXml (XmlReader reader)
{
// do what you need to do to read your object from XML
}
Using these two methods, you should be able to capture the necessary state information from just about any object you might want to store, and turn it into XML that can be persisted to disk - and deserialized back into an object when the time comes!
XmlSerializer can work for your first criteria, however you must provide the recursion for objects like the TreeView control.
BinaryFormatter can work for all 3 criteria. If a class changes, you may have to create a conversion tool to convert old format documents to a new format. Or recognize an older format, deserialize to the old, and then save to the new - keeping your old class format around for a little while.
This will help cover version tolerance which is what I think you're after: MSDN - Version Tolerant Serialization

DeSerializing an XML file to a C# class

Does anyone know what advantages (memory/speed) there are by using a class generated by the XSD tool to explore a deserialized XML file as opposed to XPATH?
I'd say the advantage is that you get a strongly typed class which is more convenient to use, and also the constructor for the class will throw an exception if the XML data in the file is invalid for creating the object, so you get a minimal data validation for free.
If you don't want to write boilerplate code, and you need to check ANY values of your XML on the way through, you can't go wrong with the XSD.exe generated classes.
The two are very different; but XmlSerializer will always deserialize entire objects; with XPath you can pick and choose. I'd use XmlSerializer personally, though - harder to get wrong.
XPath, however, is a complex beast that depends on the back-end. For example, XmlDocument (mutable) will behave differently to XPathDocument (read-only, optimized for query).

Categories

Resources