Skip to content

merge_attributes

xsdata.codegen.handlers.merge_attributes

MergeAttributes

Bases: HandlerInterface

Merge same type attr and their restrictions.

Source code in xsdata/codegen/handlers/merge_attributes.py
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class MergeAttributes(HandlerInterface):
    """Merge same type attr and their restrictions."""

    __slots__ = ()

    @classmethod
    def process(cls, target: Class):
        """Detect and process duplicate attributes.

        Cases:
            - Enumeration: remove duplicates
            - Otherwise: merge attrs and

        Args:
            target: The target class instance
        """
        if target.is_enumeration:
            cls.filter_duplicate_attrs(target)
        else:
            cls.merge_duplicate_attrs(target)

    @classmethod
    def filter_duplicate_attrs(cls, target: Class):
        """Removes duplicate attrs.

        Args:
            target: The target class instance
        """
        attrs = collections.unique_sequence(target.attrs, key="default")
        target.attrs = attrs

    @classmethod
    def merge_duplicate_attrs(cls, target: Class):
        """Find duplicate attrs and merge them.

        In order for two attrs to be considered duplicates,
        they must have the same name, namespace and tag.

        Args:
            target: The target class instance
        """
        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

                e_res = existing.restrictions
                a_res = attr.restrictions

                min_occurs = e_res.min_occurs or 0
                max_occurs = e_res.max_occurs or 1
                attr_min_occurs = a_res.min_occurs or 0
                attr_max_occurs = a_res.max_occurs or 1

                e_res.min_occurs = min(min_occurs, attr_min_occurs)
                e_res.max_occurs = max_occurs + attr_max_occurs

                if a_res.sequence is not None:
                    e_res.sequence = a_res.sequence

                existing.fixed = False
                existing.types.extend(attr.types)

        target.attrs = result
        ClassUtils.cleanup_class(target)

process(target) classmethod

Detect and process duplicate attributes.

Cases
  • Enumeration: remove duplicates
  • Otherwise: merge attrs and

Parameters:

Name Type Description Default
target Class

The target class instance

required
Source code in xsdata/codegen/handlers/merge_attributes.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@classmethod
def process(cls, target: Class):
    """Detect and process duplicate attributes.

    Cases:
        - Enumeration: remove duplicates
        - Otherwise: merge attrs and

    Args:
        target: The target class instance
    """
    if target.is_enumeration:
        cls.filter_duplicate_attrs(target)
    else:
        cls.merge_duplicate_attrs(target)

filter_duplicate_attrs(target) classmethod

Removes duplicate attrs.

Parameters:

Name Type Description Default
target Class

The target class instance

required
Source code in xsdata/codegen/handlers/merge_attributes.py
30
31
32
33
34
35
36
37
38
@classmethod
def filter_duplicate_attrs(cls, target: Class):
    """Removes duplicate attrs.

    Args:
        target: The target class instance
    """
    attrs = collections.unique_sequence(target.attrs, key="default")
    target.attrs = attrs

merge_duplicate_attrs(target) classmethod

Find duplicate attrs and merge them.

In order for two attrs to be considered duplicates, they must have the same name, namespace and tag.

Parameters:

Name Type Description Default
target Class

The target class instance

required
Source code in xsdata/codegen/handlers/merge_attributes.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
@classmethod
def merge_duplicate_attrs(cls, target: Class):
    """Find duplicate attrs and merge them.

    In order for two attrs to be considered duplicates,
    they must have the same name, namespace and tag.

    Args:
        target: The target class instance
    """
    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

            e_res = existing.restrictions
            a_res = attr.restrictions

            min_occurs = e_res.min_occurs or 0
            max_occurs = e_res.max_occurs or 1
            attr_min_occurs = a_res.min_occurs or 0
            attr_max_occurs = a_res.max_occurs or 1

            e_res.min_occurs = min(min_occurs, attr_min_occurs)
            e_res.max_occurs = max_occurs + attr_max_occurs

            if a_res.sequence is not None:
                e_res.sequence = a_res.sequence

            existing.fixed = False
            existing.types.extend(attr.types)

    target.attrs = result
    ClassUtils.cleanup_class(target)