Martijn Faassen wrote:
I'm trying to understand why in scoder2 there's the use of _fakeRootDoc in a few places. I imagine this is to work around some bugs that show up in the trunk, but I don't have enough context on what and why. Stefan, can you enlighten me? Any tests that expose this behavior in particular?
It's related to the fact that the current trunk rips Elements out of their document when you wrap them in ElementTrees. This is both incompatible to ElementTree und (IMHO) unnecessary. So, what I did was: rewrite ElementTree as a light-weight wrapper around an Element and remove its internal identity with libxml2 documents. In scoder2, Elements store their own reference to their 'Document', which is the new lxml-internal Python representation of a libxml2 document. This means that Elements can now stay in their document while being wrapped in any number of ElementTrees, as ElementTrees only refers to them as a 'virtual' root within their document. The drawback is that libxml2 actions that run on ElementTrees now cannot know by themselves which element is the actual root of the ElementTree (which is called _context_node in _ElementTree), as it is no longer the root of the document. This is what _fakeRootDoc is for. It takes an arbitrary element and its document and then temporarily creates a fake copy of the document that has a copy of the element as root. So, while the original element is still in its previously (arbitrary) position, its copy now forms the root of the fake document. (It is necessary to copy it since it must not have any siblings.) libxml2/libxslt actions are then run against that fake document, which is cleaned up (i.e. deleted) immediately after the action. One little hack is that it only copies the element, it does not do deep-copying. It should therefore be possible to access higher ancestors that are not below the _context_node of the respective ElementTree via e.g. an XSLT (like via <copy-of select="ancestors::node()"/>). I didn't test that, but I believe it is not too bad, since it is a rather rare case and somehow even fits the ElementTree idea of Elements being 'free'. I know, it might sound a little confusing at first, but I hope you got the idea. Stefan