def _parse_header(cls, xmlelements, tns): """Parse the soap:header / soap:headerfault elements <soap:headerfault message="qname" part="nmtoken" use="literal|encoded" encodingStyle="uri-list"? namespace="uri"? />* """ result = [] for element in xmlelements: attributes = element.attrib try: message_qname = as_qname(attributes['message'], element.nsmap, tns) result.append({ 'message': message_qname, 'part': attributes['part'], 'use': attributes['use'], 'encodingStyle': attributes.get('encodingStyle'), 'namespace': attributes.get('namespace'), }) except KeyError: raise exceptions.WsdlSyntaxError("Invalid soap:header(fault)") return result
def visit_complex_type(self, node, parent): """ <complexType abstract = Boolean : false block = (#all | List of (extension | restriction)) final = (#all | List of (extension | restriction)) id = ID mixed = Boolean : false name = NCName {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) </complexType> """ children = [] for child in node.iterchildren(): if child.tag == tags.annotation: continue elif child.tag == tags.simpleContent: children = self.visit_simple_content(child, node) elif child.tag == tags.complexContent: children = self.visit_complex_content(child, node) else: item = self.process(child, node) if child.tag == tags.group: assert not children children = item elif child.tag in (tags.choice, tags.sequence, tags.all): assert not children children = item elif child.tag in (tags.attribute,): children.append(item) # If the complexType's parent is an element then this type is # anonymous and should have no name defined. if parent.tag == tags.schema: name = node.get('name') is_anonymous = False else: name = parent.get('name') is_anonymous = True qname = as_qname(name, node.nsmap, self.schema._target_namespace) cls = type( name, (xsd_types.ComplexType,), {'__module__': 'zeep.xsd.types'}) xsd_type = cls(children) if not is_anonymous: self.schema.register_type(qname, xsd_type) return xsd_type
def visit_union(self, node, parent): """Defines a collection of multiple simpleType definitions. Definition:: <union id = ID memberTypes = List of QNames {any attributes with non-schema Namespace}...> Content: (annotation?, (simpleType*)) </union> :param node: The XML node :type node: lxml.etree._Element :param parent: The parent XML node :type parent: lxml.etree._Element """ # TODO members = node.get("memberTypes") types = [] if members: for member in members.split(): qname = as_qname(member, node.nsmap) xsd_type = self._get_type(qname) types.append(xsd_type) else: annotation, types = self._pop_annotation(list(node)) types = [self.visit_simple_type(t, node) for t in types] return xsd_types.UnionType(types)
def _parse_header(cls, xmlelements, tns): """Parse the soap:header / soap:headerfault elements <soap:headerfault message="qname" part="nmtoken" use="literal|encoded" encodingStyle="uri-list"? namespace="uri"? />* """ result = [] for element in xmlelements: attributes = element.attrib try: message_qname = as_qname( attributes['message'], element.nsmap, tns) result.append({ 'message': message_qname, 'part': attributes['part'], 'use': attributes['use'], 'encodingStyle': attributes.get('encodingStyle'), 'namespace': attributes.get('namespace'), }) except KeyError: raise exceptions.WsdlSyntaxError("Invalid soap:header(fault)") return result
def visit_union(self, node, parent): """Defines a collection of multiple simpleType definitions. Definition:: <union id = ID memberTypes = List of QNames {any attributes with non-schema Namespace}...> Content: (annotation?, (simpleType*)) </union> :param node: The XML node :type node: lxml.etree._Element :param parent: The parent XML node :type parent: lxml.etree._Element """ # TODO members = node.get('memberTypes') types = [] if members: for member in members.split(): qname = as_qname(member, node.nsmap) xsd_type = self._get_type(qname) types.append(xsd_type) else: annotation, types = self._pop_annotation(node.getchildren()) types = [self.visit_simple_type(t, node) for t in types] return xsd_types.UnionType(types)
def visit_complex_type(self, node, parent): """ <complexType abstract = Boolean : false block = (#all | List of (extension | restriction)) final = (#all | List of (extension | restriction)) id = ID mixed = Boolean : false name = NCName {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) </complexType> """ children = [] for child in node.iterchildren(): if child.tag == tags.annotation: continue elif child.tag == tags.simpleContent: children = self.visit_simple_content(child, node) elif child.tag == tags.complexContent: children = self.visit_complex_content(child, node) else: item = self.process(child, node) if child.tag == tags.group: assert not children children = item elif child.tag in (tags.choice, tags.sequence, tags.all): assert not children children = item elif child.tag in (tags.attribute, ): children.append(item) # If the complexType's parent is an element then this type is # anonymous and should have no name defined. if parent.tag == tags.schema: name = node.get('name') is_anonymous = False else: name = parent.get('name') is_anonymous = True qname = as_qname(name, node.nsmap, self.schema._target_namespace) cls = type(name, (xsd_types.ComplexType, ), {'__module__': 'zeep.xsd.types'}) xsd_type = cls(children) if not is_anonymous: self.schema.register_type(qname, xsd_type) return xsd_type
def visit_union(self, node, parent): """Defines a collection of multiple simpleType definitions. <union id = ID memberTypes = List of QNames {any attributes with non-schema Namespace}...> Content: (annotation?, (simpleType*)) </union> """ # TODO members = node.get('memberTypes') default_namespace = node.nsmap.get(None) types = [] if members: for member in members.split(): qname = as_qname( member, node.nsmap, default_namespace or self.document._target_namespace) xsd_type = self._get_type(qname) types.append(xsd_type) else: annotation, types = self._pop_annotation(node.getchildren()) types = [self.visit_simple_type(t, node) for t in types] return xsd_types.UnionType(types)
def process_error(self, doc, operation): fault_node = doc.find("soap-env:Body/soap-env:Fault", namespaces=self.nsmap) if fault_node is None: raise Fault( message="Unknown fault occured", code=None, actor=None, detail=etree_to_string(doc), ) def get_text(name): child = fault_node.find(name) if child is not None: return child.text message = fault_node.findtext( "soap-env:Reason/soap-env:Text", namespaces=self.nsmap ) code = fault_node.findtext( "soap-env:Code/soap-env:Value", namespaces=self.nsmap ) # Extract the fault subcodes. These can be nested, as in subcodes can # also contain other subcodes. subcodes = [] subcode_element = fault_node.find( "soap-env:Code/soap-env:Subcode", namespaces=self.nsmap ) while subcode_element is not None: subcode_value_element = subcode_element.find( "soap-env:Value", namespaces=self.nsmap ) subcode_qname = as_qname( subcode_value_element.text, subcode_value_element.nsmap, None ) subcodes.append(subcode_qname) subcode_element = subcode_element.find( "soap-env:Subcode", namespaces=self.nsmap ) # TODO: We should use the fault message as defined in the wsdl. detail_node = fault_node.find("soap-env:Detail", namespaces=self.nsmap) raise Fault( message=message, code=code, actor=None, detail=detail_node, subcodes=subcodes, )
def _parse_header_element(cls, xmlelement, tns): attributes = xmlelement.attrib message_qname = as_qname(attributes['message'], xmlelement.nsmap, tns) try: return { 'message': message_qname, 'part': attributes['part'], 'use': attributes['use'], 'encodingStyle': attributes.get('encodingStyle'), 'namespace': attributes.get('namespace'), } except KeyError: raise exceptions.WsdlSyntaxError("Invalid soap:header(fault)")
def _parse_header_element(cls, xmlelement, tns): attributes = xmlelement.attrib message_qname = as_qname(attributes["message"], xmlelement.nsmap, tns) try: return { "message": message_qname, "part": attributes["part"], "use": attributes["use"], "encodingStyle": attributes.get("encodingStyle"), "namespace": attributes.get("namespace"), } except KeyError: raise exceptions.WsdlSyntaxError("Invalid soap:header(fault)")
def _parse_header_element(cls, xmlelement, tns): attributes = xmlelement.attrib message_qname = as_qname( attributes['message'], xmlelement.nsmap, tns) try: return { 'message': message_qname, 'part': attributes['part'], 'use': attributes['use'], 'encodingStyle': attributes.get('encodingStyle'), 'namespace': attributes.get('namespace'), } except KeyError: raise exceptions.WsdlSyntaxError("Invalid soap:header(fault)")
def visit_simple_type(self, node, parent): """ Definition:: <simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any attributes with non-schema Namespace}...> Content: (annotation?, (restriction | list | union)) </simpleType> :param node: The XML node :type node: lxml.etree._Element :param parent: The parent XML node :type parent: lxml.etree._Element """ if parent.tag == tags.schema: name = node.get('name') is_global = True else: name = parent.get('name', 'Anonymous') is_global = False base_type = '{http://www.w3.org/2001/XMLSchema}string' qname = as_qname(name, node.nsmap, self.document._target_namespace) annotation, items = self._pop_annotation(node.getchildren()) child = items[0] if child.tag == tags.restriction: base_type = self.visit_restriction_simple_type(child, node) xsd_type = xsd_types.UnresolvedCustomType(qname, base_type, self.schema) elif child.tag == tags.list: xsd_type = self.visit_list(child, node) elif child.tag == tags.union: xsd_type = self.visit_union(child, node) else: raise AssertionError("Unexpected child: %r" % child.tag) assert xsd_type is not None if is_global: self.register_type(qname, xsd_type) return xsd_type
def visit_simple_type(self, node, parent): """ Definition:: <simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any attributes with non-schema Namespace}...> Content: (annotation?, (restriction | list | union)) </simpleType> :param node: The XML node :type node: lxml.etree._Element :param parent: The parent XML node :type parent: lxml.etree._Element """ if parent.tag == tags.schema: name = node.get('name') is_global = True else: name = parent.get('name', 'Anonymous') is_global = False base_type = '{http://www.w3.org/2001/XMLSchema}string' qname = as_qname(name, node.nsmap, self.document._target_namespace) annotation, items = self._pop_annotation(node.getchildren()) child = items[0] if child.tag == tags.restriction: base_type = self.visit_restriction_simple_type(child, node) xsd_type = UnresolvedCustomType(qname, base_type, self.schema) elif child.tag == tags.list: xsd_type = self.visit_list(child, node) elif child.tag == tags.union: xsd_type = self.visit_union(child, node) else: raise AssertionError("Unexpected child: %r" % child.tag) assert xsd_type is not None if is_global: self.register_type(qname, xsd_type) return xsd_type
def visit_simple_type(self, node, parent): """ <simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any attributes with non-schema Namespace}...> Content: (annotation?, (restriction | list | union)) </simpleType> """ if parent.tag == tags.schema: name = node.get('name') is_anonymous = False else: name = parent.get('name') is_anonymous = True base_type = '{http://www.w3.org/2001/XMLSchema}string' for child in node.iterchildren(): if child.tag == tags.annotation: continue elif child.tag == tags.restriction: base_type = self.visit_restriction_simple_type(child, node) break elif child.tag == tags.list: self.visit_list(child, node) break elif child.tag == tags.union: self.visit_union(child, node) break xsd_type = xsd_types.UnresolvedCustomType(name, base_type) if not is_anonymous: qname = as_qname(name, node.nsmap, self.schema._target_namespace) self.schema.register_type(qname, xsd_type) return xsd_type
def visit_simple_type(self, node, parent): """ <simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any attributes with non-schema Namespace}...> Content: (annotation?, (restriction | list | union)) </simpleType> """ if parent.tag == tags.schema: name = node.get('name') is_anonymous = False else: name = parent.get('name', 'Anonymous') is_anonymous = True base_type = '{http://www.w3.org/2001/XMLSchema}string' annotation, items = self._pop_annotation(node.getchildren()) child = items[0] if child.tag == tags.restriction: base_type = self.visit_restriction_simple_type(child, node) xsd_type = xsd_types.UnresolvedCustomType(name, base_type) elif child.tag == tags.list: xsd_type = self.visit_list(child, node) elif child.tag == tags.union: xsd_type = self.visit_union(child, node) else: raise AssertionError("Unexpected child: %r" % child.tag) assert xsd_type is not None if not is_anonymous: qname = as_qname(name, node.nsmap, self.schema._target_namespace) self.schema.register_type(qname, xsd_type) return xsd_type
def visit_simple_type(self, node, parent): """ <simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any attributes with non-schema Namespace}...> Content: (annotation?, (restriction | list | union)) </simpleType> """ if parent.tag == tags.schema: name = node.get('name') is_anonymous = False else: name = parent.get('name') is_anonymous = True for child in node.iterchildren(): if child.tag == tags.annotation: continue elif child.tag == tags.restriction: break elif child.tag == tags.list: self.visit_list(child, node) elif child.tag == tags.union: self.visit_union(child, node) base_type = xsd_builtins.String xsd_type = type(name, (base_type,), {})() if not is_anonymous: qname = as_qname(name, node.nsmap, self.schema._target_namespace) self.schema.register_type(qname, xsd_type) return xsd_type
def process_error(self, doc, operation): fault_node = doc.find( 'soap-env:Body/soap-env:Fault', namespaces=self.nsmap) if fault_node is None: raise Fault( message='Unknown fault occured', code=None, actor=None, detail=etree_to_string(doc)) def get_text(name): child = fault_node.find(name) if child is not None: return child.text message = fault_node.findtext('soap-env:Reason/soap-env:Text', namespaces=self.nsmap) code = fault_node.findtext('soap-env:Code/soap-env:Value', namespaces=self.nsmap) # Extract the fault subcodes. These can be nested, as in subcodes can # also contain other subcodes. subcodes = [] subcode_element = fault_node.find('soap-env:Code/soap-env:Subcode', namespaces=self.nsmap) while subcode_element is not None: subcode_value_element = subcode_element.find('soap-env:Value', namespaces=self.nsmap) subcode_qname = as_qname(subcode_value_element.text, subcode_value_element.nsmap, None) subcodes.append(subcode_qname) subcode_element = subcode_element.find('soap-env:Subcode', namespaces=self.nsmap) # TODO: We should use the fault message as defined in the wsdl. detail_node = fault_node.find('soap-env:Detail', namespaces=self.nsmap) raise Fault( message=message, code=code, actor=None, detail=detail_node, subcodes=subcodes)
def visit_simple_type(self, node, parent): """ <simpleType final = (#all | (list | union | restriction)) id = ID name = NCName {any attributes with non-schema Namespace}...> Content: (annotation?, (restriction | list | union)) </simpleType> """ if parent.tag == tags.schema: name = node.get('name') is_anonymous = False else: name = parent.get('name') is_anonymous = True for child in node.iterchildren(): if child.tag == tags.annotation: continue elif child.tag == tags.restriction: break elif child.tag == tags.list: self.visit_list(child, node) elif child.tag == tags.union: self.visit_list(child, node) base_type = xsd_builtins.String xsd_type = type(name, (base_type, ), {})() if not is_anonymous: qname = as_qname(name, node.nsmap, self.schema._target_namespace) self.schema.register_type(qname, xsd_type) return xsd_type
def visit_complex_type(self, node, parent): """ Definition:: <complexType abstract = Boolean : false block = (#all | List of (extension | restriction)) final = (#all | List of (extension | restriction)) id = ID mixed = Boolean : false name = NCName {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) </complexType> :param node: The XML node :type node: lxml.etree._Element :param parent: The parent XML node :type parent: lxml.etree._Element """ children = [] base_type = "{http://www.w3.org/2001/XMLSchema}anyType" # If the complexType's parent is an element then this type is # anonymous and should have no name defined. Otherwise it's global if parent.tag == tags.schema: name = node.get("name") is_global = True else: name = parent.get("name") is_global = False qname = as_qname(name, node.nsmap, self.document._target_namespace) cls_attributes = { "__module__": "zeep.xsd.dynamic_types", "_xsd_name": qname } xsd_cls = type(name, (xsd_types.ComplexType, ), cls_attributes) xsd_type = None # Process content annotation, children = self._pop_annotation(list(node)) first_tag = children[0].tag if children else None if first_tag == tags.simpleContent: base_type, attributes = self.visit_simple_content( children[0], node) xsd_type = xsd_cls( attributes=attributes, extension=base_type, qname=qname, is_global=is_global, ) elif first_tag == tags.complexContent: kwargs = self.visit_complex_content(children[0], node) xsd_type = xsd_cls(qname=qname, is_global=is_global, **kwargs) elif first_tag: element = None if first_tag in (tags.group, tags.all, tags.choice, tags.sequence): child = children.pop(0) element = self.process(child, node) attributes = self._process_attributes(node, children) xsd_type = xsd_cls(element=element, attributes=attributes, qname=qname, is_global=is_global) else: xsd_type = xsd_cls(qname=qname, is_global=is_global) if is_global: self.register_type(qname, xsd_type) return xsd_type
def visit_attribute( self, node: etree._Element, parent: etree._Element ) -> typing.Union[xsd_elements.Attribute, xsd_elements.RefAttribute]: """Declares an attribute. Definition:: <attribute default = string fixed = string form = (qualified | unqualified) id = ID name = NCName ref = QName type = QName use = (optional | prohibited | required): optional {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleType?)) </attribute> :param node: The XML node :type node: lxml.etree._Element :param parent: The parent XML node :type parent: lxml.etree._Element """ is_global = parent.tag == tags.schema # Check of wsdl:arayType array_type = node.get("{http://schemas.xmlsoap.org/wsdl/}arrayType") if array_type: match = re.match(r"([^\[]+)", array_type) if match: array_type = match.groups()[0] qname = as_qname(array_type, node.nsmap) array_type = UnresolvedType(qname, self.schema) # If the elment has a ref attribute then all other attributes cannot # be present. Short circuit that here. # Ref is prohibited on global elements (parent = schema) if not is_global: result = self.process_ref_attribute(node, array_type=array_type) if result: return result attribute_form = node.get("form", self.document._attribute_form) if attribute_form == "qualified" or is_global: name = qname_attr(node, "name", self.document._target_namespace) else: name = etree.QName(node.get("name")) annotation, items = self._pop_annotation(list(node)) if items: xsd_type = self.visit_simple_type(items[0], node) else: node_type = qname_attr(node, "type") if node_type: xsd_type = self._get_type(node_type) else: xsd_type = xsd_types.AnyType() # TODO: We ignore 'prohobited' for now required = node.get("use") == "required" default = node.get("default") attr = xsd_elements.Attribute(name, type_=xsd_type, default=default, required=required) # Only register global elements if is_global: assert name is not None self.register_attribute(name, attr) return attr
def process_error(self, doc, operation): fault_node = doc.find('soap-env:Body/soap-env:Fault', namespaces=self.nsmap) if fault_node is None: raise Fault(message='Unknown fault occured', code=None, actor=None, detail=etree_to_string(doc)) def get_text(name): child = fault_node.find(name) if child is not None: return child.text message = fault_node.findtext('soap-env:Reason/soap-env:Text', namespaces=self.nsmap) code = fault_node.findtext('soap-env:Code/soap-env:Value', namespaces=self.nsmap) # Extract the fault subcodes. These can be nested, as in subcodes can # also contain other subcodes. subcodes = [] subcode_element = fault_node.find('soap-env:Code/soap-env:Subcode', namespaces=self.nsmap) while subcode_element is not None: subcode_value_element = subcode_element.find('soap-env:Value', namespaces=self.nsmap) subcode_qname = as_qname(subcode_value_element.text, subcode_value_element.nsmap, None) subcodes.append(subcode_qname) subcode_element = subcode_element.find('soap-env:Subcode', namespaces=self.nsmap) # TODO: We should use the fault message as defined in the wsdl. detail_node = fault_node.find('soap-env:Detail', namespaces=self.nsmap) from xml.etree import ElementTree try: tech_message = detail_node.find( "ns2:servicefault/ns2:body/ns2:errorkey/ns2:designation", namespaces={ "ns2": "https://onlineservice.creditreform.de/webservice/0600-0021" }).text + " " except Exception: tech_message = "" try: tech_errorkey_message = detail_node.find( "ns2:servicefault/ns2:body/ns2:fault/ns2:errorkey/ns2:key", namespaces={ "ns2": "https://onlineservice.creditreform.de/webservice/0600-0021" }).text + ". " except Exception: tech_errorkey_message = "" try: tech_fault_message = detail_node.find( "ns2:servicefault/ns2:body/ns2:fault/ns2:errorkey/ns2:designation", namespaces={ "ns2": "https://onlineservice.creditreform.de/webservice/0600-0021" }).text except Exception: tech_fault_message = "" try: tech_detail_message = detail_node.find( "ns2:servicefault/ns2:body/ns2:fault/ns2:errorfield", namespaces={ "ns2": "https://onlineservice.creditreform.de/webservice/0600-0021" }).text except Exception: tech_detail_message = "" tech_fault = tech_message + tech_errorkey_message + tech_fault_message + tech_detail_message try: validation_message = detail_node.find( "tns:validationfault", namespaces={ "tns": "https://onlineservice.creditreform.de/webservice/0600-0021" }).text except Exception: validation_message = "" detail_node = tech_fault + validation_message raise Fault(message=message, code=code, actor=None, detail=detail_node, subcodes=subcodes)
def visit_complex_type(self, node, parent): """ <complexType abstract = Boolean : false block = (#all | List of (extension | restriction)) final = (#all | List of (extension | restriction)) id = ID mixed = Boolean : false name = NCName {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleContent | complexContent | ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?)))) </complexType> """ children = [] base_type = '{http://www.w3.org/2001/XMLSchema}anyType' # If the complexType's parent is an element then this type is # anonymous and should have no name defined. Otherwise it's global if parent.tag == tags.schema: name = node.get('name') is_global = True else: name = parent.get('name') is_global = False qname = as_qname(name, node.nsmap, self.document._target_namespace) cls_attributes = { '__module__': 'zeep.xsd.dynamic_types', '_xsd_name': qname, } xsd_cls = type(name, (xsd_types.ComplexType,), cls_attributes) xsd_type = None # Process content annotation, children = self._pop_annotation(node.getchildren()) first_tag = children[0].tag if children else None if first_tag == tags.simpleContent: base_type, attributes = self.visit_simple_content(children[0], node) xsd_type = xsd_cls( attributes=attributes, extension=base_type, qname=qname, is_global=is_global) elif first_tag == tags.complexContent: kwargs = self.visit_complex_content(children[0], node) xsd_type = xsd_cls(qname=qname, is_global=is_global, **kwargs) elif first_tag: element = None if first_tag in (tags.group, tags.all, tags.choice, tags.sequence): child = children.pop(0) element = self.process(child, node) attributes = self._process_attributes(node, children) xsd_type = xsd_cls( element=element, attributes=attributes, qname=qname, is_global=is_global) else: xsd_type = xsd_cls(qname=qname) if is_global: self.document.register_type(qname, xsd_type) return xsd_type
def visit_attribute(self, node, parent): """Declares an attribute. <attribute default = string fixed = string form = (qualified | unqualified) id = ID name = NCName ref = QName type = QName use = (optional | prohibited | required): optional {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleType?)) </attribute> """ is_global = parent.tag == tags.schema # Check of wsdl:arayType array_type = node.get('{http://schemas.xmlsoap.org/wsdl/}arrayType') if array_type: match = re.match('([^\[]+)', array_type) if match: array_type = match.groups()[0] qname = as_qname( array_type, node.nsmap, self.document._target_namespace) array_type = xsd_types.UnresolvedType(qname, self.schema) # If the elment has a ref attribute then all other attributes cannot # be present. Short circuit that here. # Ref is prohibited on global elements (parent = schema) if not is_global: result = self.process_ref_attribute(node, array_type=array_type) if result: return result attribute_form = node.get('form', self.document._attribute_form) qname = qname_attr(node, 'name', self.document._target_namespace) if attribute_form == 'qualified' or is_global: name = qname else: name = etree.QName(node.get('name')) annotation, items = self._pop_annotation(node.getchildren()) if items: xsd_type = self.visit_simple_type(items[0], node) else: node_type = qname_attr(node, 'type') if node_type: xsd_type = self._get_type(node_type) else: xsd_type = xsd_builtins.AnyType() # TODO: We ignore 'prohobited' for now required = node.get('use') == 'required' default = node.get('default') attr = xsd_elements.Attribute( name, type_=xsd_type, default=default, required=required) self.document._elm_instances.append(attr) # Only register global elements if is_global: self.document.register_attribute(qname, attr) return attr
def visit_attribute(self, node, parent): """Declares an attribute. <attribute default = string fixed = string form = (qualified | unqualified) id = ID name = NCName ref = QName type = QName use = (optional | prohibited | required): optional {any attributes with non-schema Namespace...}> Content: (annotation?, (simpleType?)) </attribute> """ is_global = parent.tag == tags.schema # Check of wsdl:arayType array_type = node.get('{http://schemas.xmlsoap.org/wsdl/}arrayType') if array_type: match = re.match('([^\[]+)', array_type) if match: array_type = match.groups()[0] qname = as_qname(array_type, node.nsmap, self.document._target_namespace) array_type = xsd_types.UnresolvedType(qname, self.schema) # If the elment has a ref attribute then all other attributes cannot # be present. Short circuit that here. # Ref is prohibited on global elements (parent = schema) if not is_global: result = self.process_ref_attribute(node, array_type=array_type) if result: return result attribute_form = node.get('form', self.document._attribute_form) qname = qname_attr(node, 'name', self.document._target_namespace) if attribute_form == 'qualified' or is_global: name = qname else: name = etree.QName(node.get('name')) annotation, items = self._pop_annotation(node.getchildren()) if items: xsd_type = self.visit_simple_type(items[0], node) else: node_type = qname_attr(node, 'type') if node_type: xsd_type = self._get_type(node_type) else: xsd_type = xsd_types.AnyType() # TODO: We ignore 'prohobited' for now required = node.get('use') == 'required' default = node.get('default') attr = xsd_elements.Attribute(name, type_=xsd_type, default=default, required=required) self.document._elm_instances.append(attr) # Only register global elements if is_global: self.document.register_attribute(qname, attr) return attr