def complex_add(document, cls, tags): complex_type = etree.Element(XSD('complexType')) complex_type.set('name', cls.get_type_name()) doc_text = cls.get_documentation() if doc_text or cls.Annotations.appinfo is not None: annotation = etree.SubElement(complex_type, XSD('annotation')) if doc_text: doc = etree.SubElement(annotation, XSD('documentation')) doc.text = doc_text _ai = cls.Annotations.appinfo if _ai is not None: appinfo = etree.SubElement(annotation, XSD('appinfo')) if isinstance(_ai, dict): dict_to_etree(_ai, appinfo) elif isinstance(_ai, str) or isinstance(_ai, unicode): appinfo.text = _ai elif isinstance(_ai, etree._Element): appinfo.append(_ai) else: from spyne.util.xml import get_object_as_xml appinfo.append(get_object_as_xml(_ai)) sequence_parent = complex_type extends = getattr(cls, '__extends__', None) type_info = cls._type_info if extends is not None: if (extends.get_type_name() == cls.get_type_name() and extends.get_namespace() == cls.get_namespace()): raise Exception("%r can't extend %r because they are both '{%s}%s'" % (cls, extends, cls.get_namespace(), cls.get_type_name())) if extends.Attributes.exc_interface: # If the parent class is private, it won't be in the schema, so we # need to act as if its attributes are part of cls as well. type_info = cls.get_simple_type_info(cls) else: complex_content = etree.SubElement(complex_type, XSD('complexContent')) extension = etree.SubElement(complex_content, XSD('extension')) extension.set('base', extends.get_type_name_ns(document.interface)) sequence_parent = extension xtba_key, xtba_type = cls.Attributes._xml_tag_body_as if xtba_key is not None: _sc = etree.SubElement(sequence_parent, XSD('simpleContent')) xtba_ext = etree.SubElement(_sc, XSD('extension')) xtba_ext.attrib['base'] = xtba_type.type.get_type_name_ns( document.interface) sequence = etree.Element(XSD('sequence')) deferred = deque() choice_tags = defaultdict(lambda: etree.Element(XSD('choice'))) for k, v in type_info.items(): assert isinstance(k, string_types) assert issubclass(v, ModelBase) a = v.Attributes if a.exc_interface: continue if issubclass(v, XmlData): continue if issubclass(v, XmlAttribute): deferred.append((k,v)) continue document.add(v, tags) name = a.sub_name if name is None: name = k #ns = a.sub_ns #if ns is not None: # name = "{%s}%s" % (ns, name) type_name_ns = v.get_type_name_ns(document.interface) if v.__extends__ is not None and v.__orig__ is not None and \ _check_extension_attrs(v) is None: type_name_ns = v.__orig__.get_type_name_ns(document.interface) member = etree.Element(a.schema_tag) if a.schema_tag == XSD('element'): member.set('name', name) member.set('type', type_name_ns) elif a.schema_tag == XSD('any') and issubclass(v, AnyXml): if a.namespace is not None: member.set('namespace', a.namespace) if a.process_contents is not None: member.set('processContents', a.process_contents) else: raise ValueError("Unhandled schema_tag / type combination. %r %r" % (v, a.schema_tag)) if a.min_occurs != 1: # 1 is the xml schema default member.set('minOccurs', str(a.min_occurs)) if a.max_occurs != 1: # 1 is the xml schema default val = a.max_occurs if val in (D('inf'), float('inf')): val = 'unbounded' else: val = str(val) member.set('maxOccurs', val) if a.default is not None: member.set('default', _prot.to_string(v, a.default)) if bool(a.nillable) != False: # False is the xml schema default member.set('nillable', 'true') v_doc_text = v.get_documentation() if v_doc_text: # Doesn't support multi-language documentation annotation = etree.SubElement(member, XSD('annotation')) doc = etree.SubElement(annotation, XSD('documentation')) doc.text = doc_text if a.xml_choice_group is None: sequence.append(member) else: choice_tags[a.xml_choice_group].append(member) sequence.extend(choice_tags.values()) if len(sequence) > 0: sequence_parent.append(sequence) _ext_elements = dict() for k,v in deferred: ao = v.attribute_of if ao is None: attribute = etree.Element(XSD('attribute')) xml_attribute_add(v, k, attribute, document) if xtba_key is None: complex_type.append(attribute) else: xtba_ext.append(attribute) continue elts = complex_type.xpath("//xsd:element[@name='%s']" % ao, namespaces={'xsd': _ns_xsd}) if len(elts) == 0: raise ValueError("Element %r not found for XmlAttribute %r." % (ao, k)) elif len(elts) > 1: raise Exception("Xpath returned more than one element %r " "for %r. Not sure what's going on here." % (elts, ao)) else: elt = elts[0] _ext = _ext_elements.get(ao, None) if _ext is None: _ct = etree.SubElement(elt, XSD('complexType')) _sc = etree.SubElement(_ct, XSD('simpleContent')) _ext = etree.SubElement(_sc, XSD('extension')) _ext_elements[ao] = _ext _ext.attrib['base'] = elt.attrib['type'] del elt.attrib['type'] attribute = etree.SubElement(_ext, XSD('attribute')) xml_attribute_add(v, k, attribute, document) document.add_complex_type(cls, complex_type) # simple node complex_type_name = cls.Attributes.sub_name or cls.get_type_name() element = etree.Element(XSD('element')) element.set('name', complex_type_name) element.set('type', cls.get_type_name_ns(document.interface)) document.add_element(cls, element)
def dict_to_parent(self, ctx, cls, inst, parent, ns, name, **_): elt = E(_gen_tagname(ns, name)) dict_to_etree(inst, elt) _append(parent, elt)
def dict_to_parent(self, ctx, cls, inst, parent, name, **kwargs): elt = E(name) dict_to_etree(inst, elt) parent.write(elt)
def complex_add(document, cls, tags): complex_type = etree.Element("{%s}complexType" % _ns_xsd) complex_type.set('name', cls.get_type_name()) if cls.Annotations.doc != '' or cls.Annotations.appinfo != None or \ cls.Annotations.__use_parent_doc__: annotation = etree.SubElement(complex_type, "{%s}annotation" % _ns_xsd) if cls.Annotations.doc != '' or cls.Annotations.__use_parent_doc__: doc = etree.SubElement(annotation, "{%s}documentation" % _ns_xsd) if cls.Annotations.__use_parent_doc__: doc.text = getattr(cls, '__doc__') else: doc.text = cls.Annotations.doc _ai = cls.Annotations.appinfo; if _ai != None: appinfo = etree.SubElement(annotation, "{%s}appinfo" % _ns_xsd) if isinstance(_ai, dict): dict_to_etree(_ai, appinfo) elif isinstance(_ai, str) or isinstance(_ai, unicode): appinfo.text = _ai elif isinstance(_ai, etree._Element): appinfo.append(_ai) else: from spyne.util.xml import get_object_as_xml appinfo.append(get_object_as_xml(_ai)) sequence_parent = complex_type extends = getattr(cls, '__extends__', None) type_info = cls._type_info if extends is not None: if (extends.get_type_name() == cls.get_type_name() and extends.get_namespace() == cls.get_namespace()): raise Exception("%r can't extend %r because they are both '{%s}%s'" % (cls, extends, cls.get_namespace(), cls.get_type_name())) if extends.Attributes.exc_interface: # If the parent class is private, it won't be in the schema, so we # need to act as if its attributes are part of cls as well. type_info = cls.get_simple_type_info(cls) else: complex_content = etree.SubElement(complex_type, "{%s}complexContent" % _ns_xsd) extension = etree.SubElement(complex_content, "{%s}extension" % _ns_xsd) extension.set('base', extends.get_type_name_ns(document.interface)) sequence_parent = extension sequence = etree.Element('{%s}sequence' % _ns_xsd) deferred = deque() choice_tags = defaultdict(lambda: etree.Element('{%s}choice' % _ns_xsd)) for k, v in type_info.items(): a = v.Attributes if a.exc_interface: continue if issubclass(v, XmlAttribute): deferred.append((k,v)) continue document.add(v, tags) name = a.sub_name ns = a.sub_ns if name is None: name = k if ns is not None: name = "{%s}%s" % (ns, name) member = etree.Element(a.schema_tag) if a.schema_tag == '{%s}element' % _ns_xsd: member.set('name', name) member.set('type', v.get_type_name_ns(document.interface)) elif a.schema_tag == '{%s}any' % _ns_xsd and \ (issubclass(v, AnyXml)): if a.namespace is not None: member.set('namespace', a.namespace) if a.process_contents is not None: member.set('processContents', a.process_contents) else: raise ValueError("Unhandled schema_tag / type combination. %r %r" % (v, a.schema_tag)) if a.min_occurs != 1: # 1 is the xml schema default member.set('minOccurs', str(a.min_occurs)) if a.max_occurs != 1: # 1 is the xml schema default val = a.max_occurs if val in (decimal.Decimal('inf'), float('inf')): val = 'unbounded' else: val = str(val) member.set('maxOccurs', val) if a.default is not None: member.set('default', a.default) if bool(a.nillable) != False: # False is the xml schema default member.set('nillable', 'true') if v.Annotations.doc != '': # Doesn't support multi-language documentation annotation = etree.SubElement(member, "{%s}annotation" % _ns_xsd) doc = etree.SubElement(annotation, "{%s}documentation" % _ns_xsd) doc.text = v.Annotations.doc if a.xml_choice_group is None: sequence.append(member) else: choice_tags[a.xml_choice_group].append(member) sequence.extend(choice_tags.values()) if len(sequence) > 0: sequence_parent.append(sequence) for k,v in deferred: ao = v.attribute_of if ao is None: # others will be added at a later loop attribute = etree.SubElement(complex_type,'{%s}attribute' % _ns_xsd) v.describe(k, attribute, document) continue elts = complex_type.xpath("//xsd:element[@name='%s']" % ao, namespaces={'xsd': _ns_xsd}) if len(elts) == 0: raise ValueError("Element %r not found for XmlAttribute %r." % (ao, k)) elif len(elts) > 1: raise Exception("Xpath returned more than one element %r " "for %r. Not sure what's going on here." % (elts, ao)) else: elt = elts[0] _ct = etree.SubElement(elt, '{%s}complexType' % _ns_xsd) _sc = etree.SubElement(_ct, '{%s}simpleContent' % _ns_xsd) _ext = etree.SubElement(_sc, '{%s}extension' % _ns_xsd) _ext.attrib['base'] = elt.attrib['type'] del elt.attrib['type'] attribute = etree.SubElement(_ext, '{%s}attribute' % _ns_xsd) v.describe(k, attribute, document) document.add_complex_type(cls, complex_type) # simple node element = etree.Element('{%s}element' % _ns_xsd) element.set('name', cls.get_type_name()) element.set('type', cls.get_type_name_ns(document.interface)) document.add_element(cls, element)
def dict_to_parent_element(prot, cls, value, tns, parent_elt, name='retval'): e = etree.SubElement(parent_elt, '{%s}%s' % (tns, name)) dict_to_etree(value, e)
def dict_to_parent(self, ctx, cls, inst, parent, ns, name): elt = E(name) dict_to_etree(inst, elt) parent.write(elt)
def any_dict_to_parent(self, ctx, cls, inst, parent, name, **kwargs): elt = E('foo') dict_to_etree(inst, elt) parent.write(elt[0])
def complex_add(document, cls): complex_type = etree.Element("{%s}complexType" % _ns_xsd) complex_type.set('name', cls.get_type_name()) if cls.Annotations.doc != '' or cls.Annotations.appinfo != None or \ cls.Annotations.__use_parent_doc__: annotation = etree.SubElement(complex_type, "{%s}annotation" % _ns_xsd) if cls.Annotations.doc != '' or cls.Annotations.__use_parent_doc__: doc = etree.SubElement(annotation, "{%s}documentation" % _ns_xsd) if cls.Annotations.__use_parent_doc__: doc.text = getattr(cls, '__doc__') else: doc.text = cls.Annotations.doc _ai = cls.Annotations.appinfo if _ai != None: appinfo = etree.SubElement(annotation, "{%s}appinfo" % _ns_xsd) if isinstance(_ai, dict): dict_to_etree(_ai, appinfo) elif isinstance(_ai, str) or isinstance(_ai, unicode): appinfo.text = _ai elif isinstance(_ai, etree._Element): appinfo.append(_ai) else: from spyne.util.xml import get_object_as_xml appinfo.append(get_object_as_xml(_ai)) sequence_parent = complex_type extends = getattr(cls, '__extends__', None) type_info = cls._type_info if extends is not None: if (extends.get_type_name() == cls.get_type_name() and extends.get_namespace() == cls.get_namespace()): raise Exception( "%r can't extend %r because they are both '{%s}%s'" % (cls, extends, cls.get_type_name(), cls.get_namespace())) if extends.Attributes.exc_interface: # If the parent class is private, it won't be in the schema, so we # need to act as if its attributes are part of cls as well. type_info = cls.get_simple_type_info(cls) else: complex_content = etree.SubElement(complex_type, "{%s}complexContent" % _ns_xsd) extension = etree.SubElement(complex_content, "{%s}extension" % _ns_xsd) extension.set('base', extends.get_type_name_ns(document.interface)) sequence_parent = extension sequence = etree.SubElement(sequence_parent, '{%s}sequence' % _ns_xsd) for k, v in type_info.items(): if issubclass(v, XmlAttribute): attribute = etree.SubElement(complex_type, '{%s}attribute' % _ns_xsd) v.describe(k, attribute, document) continue if v.Attributes.exc_interface: continue if not issubclass(v, cls): document.add(v) member = etree.SubElement(sequence, v.Attributes.schema_tag) if v.Attributes.schema_tag == '{%s}element' % _ns_xsd: member.set('name', k) member.set('type', v.get_type_name_ns(document.interface)) elif v.Attributes.schema_tag == '{%s}any' % _ns_xsd and \ (issubclass(v, AnyXml)): if v.Attributes.namespace is not None: member.set('namespace', v.Attributes.namespace) if v.Attributes.process_contents is not None: member.set('processContents', v.Attributes.process_contents) else: raise ValueError("Unhandled schema_tag / type combination. %r %r" % (v, v.Attributes.schema_tag)) if v.Attributes.min_occurs != 1: # 1 is the xml schema default member.set('minOccurs', str(v.Attributes.min_occurs)) if v.Attributes.max_occurs != 1: # 1 is the xml schema default val = v.Attributes.max_occurs if val == decimal.Decimal('inf'): val = 'unbounded' else: val = str(val) member.set('maxOccurs', val) if bool(v.Attributes.nillable ) != False: # False is the xml schema default member.set('nillable', 'true') document.add_complex_type(cls, complex_type) # simple node element = etree.Element('{%s}element' % _ns_xsd) element.set('name', cls.get_type_name()) element.set('type', cls.get_type_name_ns(document.interface)) document.add_element(cls, element)
def complex_add(document, cls): complex_type = etree.Element("{%s}complexType" % _ns_xsd) complex_type.set('name', cls.get_type_name()) if cls.Annotations.doc != '' or cls.Annotations.appinfo != None: annotation = etree.SubElement(complex_type, "{%s}annotation" % _ns_xsd) if cls.Annotations.doc != '': doc = etree.SubElement(annotation, "{%s}documentation" % _ns_xsd) doc.text = cls.Annotations.doc _ai = cls.Annotations.appinfo; if _ai != None: appinfo = etree.SubElement(annotation, "{%s}appinfo" % _ns_xsd) if isinstance(_ai, dict): dict_to_etree(_ai, appinfo) elif isinstance(_ai, str) or isinstance(_ai, unicode): appinfo.text = _ai elif isinstance(_ai, etree._Element): appinfo.append(_ai) else: from spyne.util.xml import get_object_as_xml appinfo.append(get_object_as_xml(_ai)) sequence_parent = complex_type extends = getattr(cls, '__extends__', None) if not (extends is None): if (extends.get_type_name() == cls.get_type_name() and extends.get_namespace() == cls.get_namespace()): raise Exception("%r can't extend %r because they are all '{%s}%s'" % (cls, extends, cls.get_type_name(), cls.get_namespace())) else: complex_content = etree.SubElement(complex_type, "{%s}complexContent" % _ns_xsd) extension = etree.SubElement(complex_content, "{%s}extension" % _ns_xsd) extension.set('base', extends.get_type_name_ns(document.interface)) sequence_parent = extension sequence = etree.SubElement(sequence_parent, '{%s}sequence' % _ns_xsd) for k, v in cls._type_info.items(): if issubclass(v, XmlAttribute): attribute = etree.SubElement(complex_type, '{%s}attribute' % _ns_xsd) v.describe(k, attribute, document) continue if not issubclass(v, cls): document.add(v) member = etree.SubElement(sequence, v.Attributes.schema_tag) if v.Attributes.schema_tag == '{%s}element' % _ns_xsd: member.set('name', k) member.set('type', v.get_type_name_ns(document.interface)) elif v.Attributes.schema_tag == '{%s}any' % _ns_xsd and \ (issubclass(v, AnyXml)): if v.Attributes.namespace is not None: member.set('namespace', v.Attributes.namespace) if v.Attributes.process_contents is not None: member.set('processContents', v.Attributes.process_contents) else: raise ValueError("Unhandled schema_tag / type combination. %r %r" % (v, v.Attributes.schema_tag)) if v.Attributes.min_occurs != 1: # 1 is the xml schema default member.set('minOccurs', str(v.Attributes.min_occurs)) if v.Attributes.max_occurs != 1: # 1 is the xml schema default val = v.Attributes.max_occurs if val == float('inf'): val = 'unbounded' else: val = str(val) member.set('maxOccurs', val) if bool(v.Attributes.nillable) != False: # False is the xml schema default member.set('nillable', 'true') document.add_complex_type(cls, complex_type) # simple node element = etree.Element('{%s}element' % _ns_xsd) element.set('name', cls.get_type_name()) element.set('type', cls.get_type_name_ns(document.interface)) document.add_element(cls, element)
def any_dict_to_parent(self, ctx, cls, inst, parent, name, **kwargs): elt = E('foo') dict_to_etree(inst, elt) parent.write(elt[0])
def dict_to_parent_element(prot, cls, value, tns, parent_elt, name="retval"): e = etree.SubElement(parent_elt, "{%s}%s" % (tns, name)) dict_to_etree(value, e)
def dict_to_parent(self, ctx, cls, inst, parent, ns, name): elt = E('{%s}%s' % (ns, name)) dict_to_etree(inst, elt) _append(parent, elt)
def dict_to_parent(self, ctx, cls, inst, parent, ns, name): elt = E('{%s}%s' % (ns, name)) dict_to_etree(inst, elt) _append(parent, elt)
def any_dict_to_parent(self, ctx, cls, inst, parent, name, **kwargs): elt = E(name) dict_to_etree(inst, elt) parent.write(E(name, elt))
def complex_add(document, cls, tags): complex_type = etree.Element("{%s}complexType" % _ns_xsd) complex_type.set('name', cls.get_type_name()) if cls.Annotations.doc != '' or cls.Annotations.appinfo != None or \ cls.Annotations.__use_parent_doc__: annotation = etree.SubElement(complex_type, "{%s}annotation" % _ns_xsd) if cls.Annotations.doc != '' or cls.Annotations.__use_parent_doc__: doc = etree.SubElement(annotation, "{%s}documentation" % _ns_xsd) if cls.Annotations.__use_parent_doc__: doc.text = getattr(cls, '__doc__') else: doc.text = cls.Annotations.doc _ai = cls.Annotations.appinfo if _ai != None: appinfo = etree.SubElement(annotation, "{%s}appinfo" % _ns_xsd) if isinstance(_ai, dict): dict_to_etree(_ai, appinfo) elif isinstance(_ai, str) or isinstance(_ai, unicode): appinfo.text = _ai elif isinstance(_ai, etree._Element): appinfo.append(_ai) else: from spyne.util.xml import get_object_as_xml appinfo.append(get_object_as_xml(_ai)) sequence_parent = complex_type extends = getattr(cls, '__extends__', None) type_info = cls._type_info if extends is not None: if (extends.get_type_name() == cls.get_type_name() and extends.get_namespace() == cls.get_namespace()): raise Exception( "%r can't extend %r because they are both '{%s}%s'" % (cls, extends, cls.get_namespace(), cls.get_type_name())) if extends.Attributes.exc_interface: # If the parent class is private, it won't be in the schema, so we # need to act as if its attributes are part of cls as well. type_info = cls.get_simple_type_info(cls) else: complex_content = etree.SubElement(complex_type, "{%s}complexContent" % _ns_xsd) extension = etree.SubElement(complex_content, "{%s}extension" % _ns_xsd) extension.set('base', extends.get_type_name_ns(document.interface)) sequence_parent = extension sequence = etree.Element('{%s}sequence' % _ns_xsd) deferred = deque() choice_tags = defaultdict(lambda: etree.Element('{%s}choice' % _ns_xsd)) for k, v in type_info.items(): a = v.Attributes if a.exc_interface: continue if issubclass(v, XmlAttribute): deferred.append((k, v)) continue document.add(v, tags) name = a.sub_name ns = a.sub_ns if name is None: name = k if ns is not None: name = "{%s}%s" % (ns, name) member = etree.Element(a.schema_tag) if a.schema_tag == '{%s}element' % _ns_xsd: member.set('name', name) member.set('type', v.get_type_name_ns(document.interface)) elif a.schema_tag == '{%s}any' % _ns_xsd and \ (issubclass(v, AnyXml)): if a.namespace is not None: member.set('namespace', a.namespace) if a.process_contents is not None: member.set('processContents', a.process_contents) else: raise ValueError("Unhandled schema_tag / type combination. %r %r" % (v, a.schema_tag)) if a.min_occurs != 1: # 1 is the xml schema default member.set('minOccurs', str(a.min_occurs)) if a.max_occurs != 1: # 1 is the xml schema default val = a.max_occurs if val in (decimal.Decimal('inf'), float('inf')): val = 'unbounded' else: val = str(val) member.set('maxOccurs', val) if a.default is not None: member.set('default', _prot.to_string(v, a.default)) if bool(a.nillable) != False: # False is the xml schema default member.set('nillable', 'true') if v.Annotations.doc != '': # Doesn't support multi-language documentation annotation = etree.SubElement(member, "{%s}annotation" % _ns_xsd) doc = etree.SubElement(annotation, "{%s}documentation" % _ns_xsd) doc.text = v.Annotations.doc if a.xml_choice_group is None: sequence.append(member) else: choice_tags[a.xml_choice_group].append(member) sequence.extend(choice_tags.values()) if len(sequence) > 0: sequence_parent.append(sequence) for k, v in deferred: ao = v.attribute_of if ao is None: # others will be added at a later loop attribute = etree.SubElement(complex_type, '{%s}attribute' % _ns_xsd) xml_attribute_add(v, k, attribute, document) continue elts = complex_type.xpath("//xsd:element[@name='%s']" % ao, namespaces={'xsd': _ns_xsd}) if len(elts) == 0: raise ValueError("Element %r not found for XmlAttribute %r." % (ao, k)) elif len(elts) > 1: raise Exception("Xpath returned more than one element %r " "for %r. Not sure what's going on here." % (elts, ao)) else: elt = elts[0] _ct = etree.SubElement(elt, '{%s}complexType' % _ns_xsd) _sc = etree.SubElement(_ct, '{%s}simpleContent' % _ns_xsd) _ext = etree.SubElement(_sc, '{%s}extension' % _ns_xsd) _ext.attrib['base'] = elt.attrib['type'] del elt.attrib['type'] attribute = etree.SubElement(_ext, '{%s}attribute' % _ns_xsd) xml_attribute_add(v, k, attribute, document) document.add_complex_type(cls, complex_type) # simple node complex_type_name = cls.Attributes.sub_name or cls.get_type_name() element = etree.Element('{%s}element' % _ns_xsd) element.set('name', complex_type_name) element.set('type', cls.get_type_name_ns(document.interface)) document.add_element(cls, element)
def any_dict_to_parent(self, ctx, cls, inst, parent, ns, name, **_): elt = E(_gen_tagname(ns, name)) dict_to_etree(inst, elt) _append(parent, elt)
def complex_add(document, cls, tags): complex_type = etree.Element(XSD('complexType')) complex_type.set('name', cls.get_type_name()) doc_text = cls.get_documentation() if doc_text or cls.Annotations.appinfo is not None: annotation = etree.SubElement(complex_type, XSD('annotation')) if doc_text: doc = etree.SubElement(annotation, XSD('documentation')) doc.text = doc_text _ai = cls.Annotations.appinfo if _ai is not None: appinfo = etree.SubElement(annotation, XSD('appinfo')) if isinstance(_ai, dict): dict_to_etree(_ai, appinfo) elif isinstance(_ai, string_types): appinfo.text = _ai elif isinstance(_ai, etree._Element): appinfo.append(_ai) else: from spyne.util.xml import get_object_as_xml appinfo.append(get_object_as_xml(_ai)) sequence_parent = complex_type extends = getattr(cls, '__extends__', None) type_info = cls._type_info if extends is not None: if (extends.get_type_name() == cls.get_type_name() and extends.get_namespace() == cls.get_namespace()): raise Exception( "%r can't extend %r because they are both '{%s}%s'" % (cls, extends, cls.get_namespace(), cls.get_type_name())) if extends.Attributes.exc_interface: # If the parent class is private, it won't be in the schema, so we # need to act as if its attributes are part of cls as well. type_info = cls.get_simple_type_info(cls) else: complex_content = etree.SubElement(complex_type, XSD('complexContent')) extension = etree.SubElement(complex_content, XSD('extension')) extension.set('base', extends.get_type_name_ns(document.interface)) sequence_parent = extension if cls.Attributes._xml_tag_body_as is not None: for xtba_key, xtba_type in cls.Attributes._xml_tag_body_as: _sc = etree.SubElement(sequence_parent, XSD('simpleContent')) xtba_ext = etree.SubElement(_sc, XSD('extension')) xtba_ext.attrib['base'] = xtba_type.type.get_type_name_ns( document.interface) sequence = etree.Element(XSD('sequence')) deferred = deque() choice_tags = defaultdict(lambda: etree.Element(XSD('choice'))) for k, v in type_info.items(): assert isinstance(k, string_types) assert issubclass(v, ModelBase) a = v.Attributes if a.exc_interface: continue if issubclass(v, XmlData): continue if issubclass(v, XmlAttribute): deferred.append((k, v)) continue document.add(v, tags) name = a.sub_name if name is None: name = k #ns = a.sub_ns #if ns is not None: # name = "{%s}%s" % (ns, name) type_name_ns = v.get_type_name_ns(document.interface) if v.__extends__ is not None and v.__orig__ is not None and \ _check_extension_attrs(v) is None: type_name_ns = v.__orig__.get_type_name_ns(document.interface) member = etree.Element(a.schema_tag) if a.schema_tag == XSD('element'): member.set('name', name) member.set('type', type_name_ns) elif a.schema_tag == XSD('any') and issubclass(v, AnyXml): if a.namespace is not None: member.set('namespace', a.namespace) if a.process_contents is not None: member.set('processContents', a.process_contents) else: raise ValueError("Unhandled schema_tag / type combination. %r %r" % (v, a.schema_tag)) if a.min_occurs != 1: # 1 is the xml schema default member.set('minOccurs', str(a.min_occurs)) if a.max_occurs != 1: # 1 is the xml schema default val = a.max_occurs if val in (D('inf'), float('inf')): val = 'unbounded' else: val = str(val) member.set('maxOccurs', val) if a.default is not None: member.set('default', _prot.to_unicode(v, a.default)) if bool(a.nillable) != False: # False is the xml schema default member.set('nillable', 'true') v_doc_text = v.get_documentation() if v_doc_text: # Doesn't support multi-language documentation annotation = etree.SubElement(member, XSD('annotation')) doc = etree.SubElement(annotation, XSD('documentation')) doc.text = v_doc_text if a.xml_choice_group is None: sequence.append(member) else: choice_tags[a.xml_choice_group].append(member) sequence.extend(choice_tags.values()) if len(sequence) > 0: sequence_parent.append(sequence) _ext_elements = dict() for k, v in deferred: attribute = etree.Element(XSD('attribute')) xml_attribute_add(v, k, attribute, document) if cls.Attributes._xml_tag_body_as is None: sequence_parent.append(attribute) else: xtba_ext.append(attribute) document.add_complex_type(cls, complex_type) # simple node complex_type_name = cls.Attributes.sub_name or cls.get_type_name() element = etree.Element(XSD('element')) element.set('name', complex_type_name) element.set('type', cls.get_type_name_ns(document.interface)) document.add_element(cls, element)