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!
Related
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
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.
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
Our system stores XML strings in a database. I've recently had to change the Properties on a Class, and now when an XML string gets deserialized it will throw an exception. What is the best way to handle this change? Look for the Node in the application code using XPATH or LINQ, or change the xml string in sql database (ie do a mass update)?.
You might want to look at writing a custom XML deserializer (i.e. implementing IXmlSerializable, see here) to handle changes in your XML. If you've invested a lot of time into crafting your XML serialization attributes, you may want to look at another approach.
Consider batch-upgrading your XML, or deprecating (instead of removing) properties inside of your classes and mapping older behavior to newer behavior.
Longer term, you will want to come up with a strategy for dealing with this in the future, since you will most likely be continue to make changes to your schema/object definitions as you add/change the functionality of your system.
if you serialize the objects to the database you could try the approach I outlined here to load the old versions into a new version then when you save the new version will be saved. Not sure if having different versions of your class will be appropriate though...
Basically you create a factory to produce your objects from the xml. everytime you change your object you create a new factory and a new object class, which is given a version of the old class in its constructor and it creates itself from the old class. The new factory tries to create a new object from the xml, if it can, happy days, if it can't then it creates a new object and tells the next oldest factory to create a next oldest object from the xml. These factories can then be chained together so that you can always load a newest version of the objects from whatever data is in the db.
This assumes that its possible to always create a valid v2 object from a v1 object.
It's a good practice to store a version along your XML strings. Either at the database level or at the class level so that your code knows which version of the class it has to deserialize.
You might also look at XSLT. It allows you to transform one version of XML into another.
In that case the logic to go from one version to another is not handle by code but by the XSLT. You can even store the XSLT into the database which makes it reusable by other programs.