[Lxml-checkins] r43386 - in lxml/trunk: . doc src/lxml
scoder at codespeak.net
scoder at codespeak.net
Mon May 14 22:42:52 CEST 2007
Author: scoder
Date: Mon May 14 22:42:51 2007
New Revision: 43386
Modified:
lxml/trunk/CHANGES.txt
lxml/trunk/doc/objectify.txt
lxml/trunk/src/lxml/objectify.pyx
Log:
objectify didn't handle prefixed type names in xsi:type
Modified: lxml/trunk/CHANGES.txt
==============================================================================
--- lxml/trunk/CHANGES.txt (original)
+++ lxml/trunk/CHANGES.txt Mon May 14 22:42:51 2007
@@ -44,6 +44,8 @@
Bugs fixed
----------
+* Objectify couldn't handle prefixed XSD type names in ``xsi:type``
+
* More ET compatible behaviour when writing out XML declarations or not
* More robust error handling in ``iterparse()``
Modified: lxml/trunk/doc/objectify.txt
==============================================================================
--- lxml/trunk/doc/objectify.txt (original)
+++ lxml/trunk/doc/objectify.txt Mon May 14 22:42:51 2007
@@ -733,22 +733,23 @@
and/or 'xsi:type' information::
>>> root = objectify.fromstring('''\
- ... <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- ... <d xsi:type="double">5</d>
- ... <l xsi:type="long" >5</l>
- ... <s xsi:type="string">5</s>
+ ... <root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ ... xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ ... <d xsi:type="xsd:double">5</d>
+ ... <l xsi:type="xsd:long" >5</l>
+ ... <s xsi:type="xsd:string">5</s>
... </root>''')
>>> objectify.annotate(root)
>>> print objectify.dump(root)
root = None [ObjectifiedElement]
d = 5.0 [FloatElement]
- * xsi:type = 'double'
+ * xsi:type = 'xsd:double'
* py:pytype = 'float'
l = 5L [LongElement]
- * xsi:type = 'long'
+ * xsi:type = 'xsd:long'
* py:pytype = 'long'
s = '5' [StringElement]
- * xsi:type = 'string'
+ * xsi:type = 'xsd:string'
* py:pytype = 'str'
>>> objectify.deannotate(root)
>>> print objectify.dump(root)
@@ -780,7 +781,7 @@
root = None [ObjectifiedElement]
x = 5L [LongElement]
* py:pytype = 'long'
- * xsi:type = 'integer'
+ * xsi:type = 'xsd:integer'
There is a side effect of the type lookup. If you assign a string value using
attribute assignment and that string value turns out to be valid for any of
Modified: lxml/trunk/src/lxml/objectify.pyx
==============================================================================
--- lxml/trunk/src/lxml/objectify.pyx (original)
+++ lxml/trunk/src/lxml/objectify.pyx Mon May 14 22:42:51 2007
@@ -1011,12 +1011,13 @@
xsi_ns = "{%s}" % XML_SCHEMA_INSTANCE_NS
pytype_ns = "{%s}" % PYTYPE_NAMESPACE
for name, value in cetree.iterattributes(element, 3):
- if name == PYTYPE_ATTRIBUTE:
- if value == TREE_PYTYPE:
- continue
- else:
- name = name.replace(pytype_ns, 'py:')
- name = name.replace(xsi_ns, 'xsi:')
+ if '{' in name:
+ if name == PYTYPE_ATTRIBUTE:
+ if value == TREE_PYTYPE:
+ continue
+ else:
+ name = name.replace(pytype_ns, 'py:')
+ name = name.replace(xsi_ns, 'xsi:')
result = result + "%s * %s = %r\n" % (indentstr, name, value)
indent = indent + 1
@@ -1097,6 +1098,9 @@
if value is not None:
dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, value)
+ if dict_result is NULL and ':' in value:
+ prefix, value = value.split(':', 1)
+ dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, value)
if dict_result is not NULL:
return (<PyType>dict_result)._type
@@ -1516,6 +1520,9 @@
if value is not None:
dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, value)
+ if dict_result is NULL and ':' in value:
+ prefix, value = value.split(':', 1)
+ dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, value)
if dict_result is not NULL:
pytype = <PyType>dict_result
@@ -1574,6 +1581,9 @@
c_node, _XML_SCHEMA_INSTANCE_NS, "type")
if typename is not None:
dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, typename)
+ if dict_result is NULL and ':' in typename:
+ prefix, typename = typename.split(':', 1)
+ dict_result = python.PyDict_GetItem(_SCHEMA_TYPE_DICT, typename)
if dict_result is not NULL:
pytype = <PyType>dict_result
if pytype is not StrType:
@@ -1617,6 +1627,15 @@
cetree.delAttributeFromNsName(c_node, _XML_SCHEMA_INSTANCE_NS, "type")
else:
# update or create attribute
+ c_ns = cetree.findOrBuildNodeNs(doc, c_node, _XML_SCHEMA_NS)
+ if c_ns is not NULL:
+ if c_ns.prefix is not NULL and c_ns.prefix[0] != c'\0':
+ if ':' in typename:
+ oldprefix, name = typename.split(':', 1)
+ if cstd.strcmp(_cstr(oldprefix), c_ns.prefix) != 0:
+ typename = c_ns.prefix + ':' + name
+ elif ':' in typename:
+ _, typename = typename.split(':', 1)
c_ns = cetree.findOrBuildNodeNs(doc, c_node, _XML_SCHEMA_INSTANCE_NS)
tree.xmlSetNsProp(c_node, c_ns, "type", _cstr(typename))
tree.END_FOR_EACH_ELEMENT_FROM(c_node)
@@ -1729,6 +1748,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:
@@ -1736,12 +1756,30 @@
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 TypeError, "XSD types require the XSD namespace"
+ elif nsmap is _DEFAULT_NSMAP:
+ name = _xsi
+ _xsi = 'xsd' + ':' + _xsi
+ else:
+ name = _xsi
+ for p, ns in nsmap.items():
+ if ns == XML_SCHEMA_NS:
+ _xsi = prefix + ':' + _xsi
+ break
+ else:
+ raise TypeError, "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
More information about the lxml-checkins
mailing list