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.
Related
Initially I had various XSD definition for each XSD I had set of XML files stored.
After some time duration there are some changes in XSD definition so my stored XML is no more validation again new XSD.
For support I need to write XSLT and do changes in my stored XML to validate again new XSD.
Now, in this scenario each time XSD change, I need to write XSLT manually how can I generate this XSLT dynamically.
Currently I am able compare old and new XSD and get the list what is changes using Microsoft.XmlDiffPatch DLL.
Based on this changes I need to generate XSLT using C#.
I don't know what your question is, but I think this is technically possible.
It might be easier to just write some c# code that reads the Xml and then augments it and sets it back to the file/database/dataStore.
Not sure there is a magic bullet for this. Sounds like you're in for some work, and I'd advise that whatever you do be as reusable as possible in the face of future changes.
You might want to consider using xproc (via Calabash or some other engine) to create an XML pipeline whereby you detect and pass in changes of an XSD into an XSL (perhaps keeping to the convention of one XSL per XSD, to retain your sanity), and then said XSLs take those changes and handle them for all XML files bound by the XSD whose changes are being handled at the moment. Breaking all these into sub-transformations within the pipeline could be possible, and might make things more reusable in the future.
Inside the XSLs you're likely looking at doing something like:
for all changes to be made
for each XML
match/add/delete per element and/or attribute to implement change
One way to represent the changes to be made in some sort of standard format is as an incoming list of operations to perform and associated elements/attrs to act upon (maybe set it up as key/value pairs). Each operation could be a string (add, delete, convert) or a numeric code. You then traverse the list of ops and associated elements and trigger matches to accommodate.
This is all somewhat abstract because I have no idea of the scope or depth of changes you need to make. I'm really just thinking out loud here. You might just have to knuckle down and do some serious one-time work, then implement some sort of change control process to make sure things don't get out of hand in the future.
Hope this helps. Good luck!
I'm wondering is there any way to handle deserialisation after changing a classes, namespace?
At the moment I'm having to do an edit replace on the text value of the XML replacing old namespace with new namespace.
Is there a better way to do this?
Always a tricky one. Unless you can guarantee that the class won't change, then it's probably best to find another approach to serializing.
However, to answer the question, you could have a Version property of the class (or put it in a base class if you have many). You'll need to remember to increment this whenever you change the class.
Then you could have a series of "migrations", which would know how to transform the XML from one version to the next. When you want to deserialize, first load the file as XML, apply the migrations in turn (as there may have been several changes since the file was created), and then deserialize the now transformed XML.
I have a complex graph of XML-serializable classes that I'm able to (de)serialize to hard-disk just fine. But how do I handle massive changes to the graph schema structure? Is there some mechanism to handle XML schema upgrades? Some classes that would allow me to migrate old data to the new format?
Sure I could just use XmlReader/XmlWriter, go through every node and attribute and write several thousand lines of code to convert data to the new format, but maybe there is a better way?
I have found Object graph serialization in .NET and code version upgrades, but I don't think the linked articles apply when there are major changes in the model.
Instead of writing several thousand lines of code to convert files using XmlReader / XmlWriter, you could use XSLT. We are still talking hundreds of lines of code, and perhaps slower execution speeds, but if you are good at XSLT you could get it done much faster.
The other approach would be to build a C# program that links both the old class and the new class (of course you'd need to rename the old class to avoid naming collision). The program would load OldMyClass from disk, construct NewMyClass from the values of its attributes, and serialize NewMyClass to disk. Essentially, this approach moves the task of conversion into the C# territory, which may be a lot more familiar to you.
In this case, i keep my changes in my object and recreate my xml through the XmlSerializer: http://support.microsoft.com/kb/815813
With this i load and save new xml schema based in my object.
When I am editing an XML document that has an XmlSchema, how can I programmatically determine the elements that can be inserted next? I am using C# and I already know which element I am in. Is there an MSXML method I can call or something else? Thanks.
Sounds like you are after the .Net Schema Object Model (SOM)
Schema Object Model
Here is an article on how to work with the SOM.
Example 1
Tarzan,
As I understand it, you are trying to determine the legal XML that can be added at a specific place in the document, based on the schema being used. If that is correct, it is a very difficult problem to solve. If you have an "any" element in your XSD, your complexity increases because you can literally be any element! Also, XSD schemas can be subclassed (i.e., an element definition structure based on another structure), then that introduces more complexity. There are only couple of products (Oxygen, Visual Studio) that have attempted this with any success (that I know of).
If your schema is fairly simple, and doesn't include any of these deal breakers, you might be able to use the Schema Object Model to find the legal elements at your current location, but only if you know what portion of the XSD applies to your current element.
Does this make sense?
Erick
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