2012/10/16 Johan Engelen <jbc.engelen@...2592...>:
Your solution works for guides, but will not work for example for grids (old-style grid is not an XML element, it is part of sp-namedview).
Then this is also a change in the XML mapping of sp-namedview. In this case, you just need to construct the child XML node for the grid and add it to the tree before calling the parent class build function (in this case SPObjectGroup::build, which will create and call invoke_build on its children).
I don't see why we have to make a whole object of this and do it on the fly while creating the object tree. I think it is much simpler and better if we do all backwards compatibility fix-ups at the start before creating all the objects from it, in a centralized place. And do these things one after another even:
file XML load; // 0.46 grids definition changed: CanvasGrid::upgradeTo046(xml document); // 0.50 guide and grid definition changed: CanvasGrid::upgradeTo050(xml document); SPGuide::upgradeTo050(...); continue with XML parsing to create the SPObject tree
This may break for exotic cases where things are lost in translation, but there is no reason to strictly adhere to this stacking of compatibility functions (first ->0.46 and then ->0.50) if it does not come natural.
This would require each of these functions to traverse the entire XML tree, which is rather wasteful and requires repetitive code. If you want to do it this way, the tree should be traversed only once and the required conversion functions called whenever the current XML element has a matching element name or sodipodi:type atribute, preferably using a lookup in std::map or std::tr1::unordered_map.
As long as the object upgrade functions are defined in the files of respective SPObjects and are only called by the file upgrade function on relevant XML nodes (e.g. they don't need to reimplement tree traversal), this may be a workable solution.
Regards, Krzysztof