
Hi,
You're not gonna let go, are you? :)
But I think you're right. I'll patch those two in. I'll need you to check that these things work, though. The test coverage in that area is not very great, since I had to leave out a couple of those big test cases as they wouldn't work without having lxml also generate the prefixes.
I propose changing DataElement() like this to come even closer to future behaviour, without internal auto-prefixing; this is actually just taken from trunk and left out the internal prefix addition: Index: src/lxml/objectify.pyx =================================================================== --- src/lxml/objectify.pyx (revision 44327) +++ src/lxml/objectify.pyx (working copy) @@ -1664,6 +1664,7 @@ if the type can be identified. If '_pytype' or '_xsi' are among the keyword arguments, they will be used instead. """ + cdef python.PyObject* dict_result if nsmap is None: nsmap = _DEFAULT_NSMAP if attrib is not None: @@ -1671,12 +1672,19 @@ attrib.update(_attributes) _attributes = attrib if _xsi is not None: + if ':' in _xsi: + prefix, name = _xsi.split(':', 1) + ns = nsmap.get(prefix) + if ns != XML_SCHEMA_NS: + raise ValueError, "XSD types require the XSD namespace" python.PyDict_SetItem(_attributes, XML_SCHEMA_INSTANCE_TYPE_ATTR, _xsi) if _pytype is None: - # allow for s.o. using unregistered or even wrong xsi:type names - pytype_lookup = _SCHEMA_TYPE_DICT.get(_xsi) - if pytype_lookup is not None: - _pytype = pytype_lookup.name + # allow using unregistered or even wrong xsi:type names + dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, _xsi) + if dict_result is NULL: + dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, name) + if dict_result is not NULL: + _pytype = (<PyType>dict_result).name if python._isString(_value): strval = _value This way, you can use type prefixes in DataElement if you wish, with the lookup being able to use the information:
root = objectify.Element('root') root.no_prefix = DataElement(5, _xsi="long") root.prefix = DataElement(5, _xsi="xsd:long") print etree.tostring(root, pretty_print="True") <root xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" py:pytype="TREE"> <no_prefix py:pytype="long" xsi:type="long">5</no_prefix> <prefix py:pytype="long" xsi:type="xsd:long">5</prefix> </root>
Note how the <prefix> element gets identified as pytype "long" (as opposed to pytype "int"). It's easy to also remove the check for a given ns-prefix pointing to XML_SCHEMA_NS but I think it's compatible enough to 1.2.1 behaviour. Patch file attached. Holger -- GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS. Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail