def process(cls, target: Class): """ Detect same type attributes in order to merge them together with their restrictions. Two attributes are considered equal if they have the same name, types and namespace. """ result: List[Attr] = [] for attr in target.attrs: pos = collections.find(result, attr) existing = result[pos] if pos > -1 else None if not existing: result.append(attr) elif not (attr.is_attribute or attr.is_enumeration): existing.help = existing.help or attr.help min_occurs = existing.restrictions.min_occurs or 0 max_occurs = existing.restrictions.max_occurs or 1 attr_min_occurs = attr.restrictions.min_occurs or 0 attr_max_occurs = attr.restrictions.max_occurs or 1 existing.restrictions.min_occurs = min(min_occurs, attr_min_occurs) existing.restrictions.max_occurs = max_occurs + attr_max_occurs existing.fixed = False existing.restrictions.sequential = ( existing.restrictions.sequential or attr.restrictions.sequential ) target.attrs = result
def process_enum_extension(cls, source: Class, target: Class, ext: Extension): """ Process enumeration class extension. Extension cases: 1. Enumeration: copy all attr properties 2. Simple type: copy value attr properties 3. Complex type: 3.1 Target has one member, clone source and set fixed default value 3.2 Invalid schema. """ if source.is_enumeration: source_attrs = {attr.name: attr for attr in source.attrs} target.attrs = [ source_attrs[attr.name].clone() if attr.name in source_attrs else attr for attr in target.attrs ] target.extensions.remove(ext) elif len(source.attrs) == 1: source_attr = source.attrs[0] for attr in target.attrs: attr.types.extend([x.clone() for x in source_attr.types]) attr.restrictions.merge(source_attr.restrictions) target.extensions.remove(ext) elif len(target.attrs) == 1: # We are not an enumeration pal. default = target.attrs[0].default target.attrs = [attr.clone() for attr in source.attrs] target.extensions = [ext.clone() for ext in source.extensions] for attr in target.attrs: if attr.xml_type is None: attr.default = default attr.fixed = True else: raise CodeGenerationError( "Enumeration class with a complex extension.")
def process(cls, target: Class): """Drop non enum attributes from enum classes.""" enumerations = [attr for attr in target.attrs if attr.is_enumeration] if enumerations: target.attrs = enumerations
def filter(cls, target: Class): """Filter attrs not derived from xs:enumeration if there are any xs:enumeration attrs.""" enumerations = [attr for attr in target.attrs if attr.is_enumeration] if enumerations: target.attrs = enumerations