So I did some research on this. This bug exists because here:
| tree.xmlOutputBufferWriteEscape(self._c_out, _xcstr(value), NULL) |
the wrong string output function is used. xmlOutputBufferWriteEscape is for writing text into tag bodies, not attribute values.
I'm inclined to say that the function that we rather need to use is xmlBufAttrSerializeTxtContent, here:
As can be seen, this is a non-trivial function so I'd be reluctant to copy it to lxml source.
However, it takes an xmlAttrPtr, which we don't seem to have at that point in lxml source code.
I'm not sure how to proceed from here. Any ideas?