def visit_element(self, node, parent): """ Definition:: <element abstract = Boolean : false block = (#all | List of (extension | restriction | substitution)) default = string final = (#all | List of (extension | restriction)) fixed = string form = (qualified | unqualified) id = ID maxOccurs = (nonNegativeInteger | unbounded) : 1 minOccurs = nonNegativeInteger : 1 name = NCName nillable = Boolean : false ref = QName substitutionGroup = QName type = QName {any attributes with non-schema Namespace}...> Content: (annotation?, ( (simpleType | complexType)?, (unique | key | keyref)*)) </element> :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 # minOccurs / maxOccurs are not allowed on global elements if not is_global: min_occurs, max_occurs = _process_occurs_attrs(node) else: max_occurs = 1 min_occurs = 1 # If the element 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: # Naive workaround to mark fields which are part of a choice element # as optional if parent.tag == tags.choice: min_occurs = 0 result = self.process_reference(node, min_occurs=min_occurs, max_occurs=max_occurs) if result: return result element_form = node.get("form", self.document._element_form) if element_form == "qualified" or is_global: qname = qname_attr(node, "name", self.document._target_namespace) else: qname = etree.QName(node.get("name").strip()) children = list(node) xsd_type = None if children: value = None for child in children: if child.tag == tags.annotation: continue elif child.tag in (tags.simpleType, tags.complexType): assert not value xsd_type = self.process(child, node) if not xsd_type: node_type = qname_attr(node, "type") if node_type: xsd_type = self._get_type(node_type.text) else: xsd_type = xsd_types.AnyType() nillable = node.get("nillable") == "true" default = node.get("default") element = xsd_elements.Element( name=qname, type_=xsd_type, min_occurs=min_occurs, max_occurs=max_occurs, nillable=nillable, default=default, is_global=is_global, ) # Only register global elements if is_global: self.register_element(qname, element) return element
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 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