Skip to content

# schema

## `xsdata.codegen.mappers.schema`

### `SchemaMapper`

Map a schema instance to classes.

This mapper is used to build classes from xsd documents.

Source code in `xsdata/codegen/mappers/schema.py`

     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
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399

    class SchemaMapper:
        """Map a schema instance to classes.

        This mapper is used to build classes from xsd documents.
        """

        @classmethod
        def map(cls, schema: Schema) -> list[Class]:
            """Map schema children elements to classes.

            Args:
                schema: The schema instance

            Returns:
                A list of classes.
            """
            assert schema.location is not None

            location = schema.location
            target_namespace = schema.target_namespace

            return [
                cls.build_class(element, container, location, target_namespace)
                for container, element in cls.root_elements(schema)
            ]

        @classmethod
        def root_elements(cls, schema: Schema) -> Iterator[tuple[str, ElementBase]]:
            """Return the schema root elements.

            Qualified Elements:
                - SimpleType
                - ComplexType
                - Group
                - AttributeGroup
                - Element
                - Attribute

            Args:
                schema: The schema instance

            Yields:
                An iterator of element base instances.
            """

            def condition(item: ElementBase) -> bool:
                return isinstance(item, ROOT_CLASSES)

            for override in schema.overrides:
                for child in override.children(condition=condition):
                    yield Tag.OVERRIDE, child

            for redefine in schema.redefines:
                for child in redefine.children(condition=condition):
                    yield Tag.REDEFINE, child

            for child in schema.children(condition=condition):
                yield Tag.SCHEMA, child

        @classmethod
        def build_class(
            cls,
            obj: ElementBase,
            container: str,
            location: str,
            target_namespace: str | None,
        ) -> Class:
            """Build and return a class instance.

            Args:
                obj: The element base instance
                container: The container name
                location: The schema location
                target_namespace: The schema target namespace

            Returns:
                The new class instance.
            """
            instance = Class(
                qname=build_qname(target_namespace, obj.real_name),
                abstract=obj.is_abstract,
                namespace=cls.element_namespace(obj, target_namespace),
                mixed=obj.is_mixed,
                nillable=obj.is_nillable,
                tag=obj.class_name,
                container=container,
                help=obj.display_help,
                ns_map=obj.ns_map,
                location=location,
                default=obj.default_value,
                fixed=obj.is_fixed,
                substitutions=cls.build_substitutions(obj, target_namespace),
            )

            cls.build_class_extensions(obj, instance)
            cls.build_class_attributes(obj, instance)
            return instance

        @classmethod
        def build_substitutions(
            cls,
            obj: ElementBase,
            target_namespace: str | None,
        ) -> list[str]:
            """Builds a list of qualified substitution group names.

            Args:
                obj: The element base instance
                target_namespace: The schema target namespace

            Returns:
                A list of qualified substitution group names.
            """
            return [
                build_qname(obj.ns_map.get(prefix, target_namespace), suffix)
                for prefix, suffix in map(text.split, obj.substitutions)
            ]

        @classmethod
        def build_class_attributes(cls, obj: ElementBase, target: Class):
            """Build the target class attrs from the element children.

            Args:
                obj: The element base instance
                target: The target class instance
            """
            base_restrictions = Restrictions.from_element(obj)
            for child, restrictions in cls.element_children(obj, base_restrictions):
                cls.build_class_attribute(target, child, restrictions)

            target.attrs.sort(key=lambda x: x.index)

        @classmethod
        def build_class_extensions(cls, obj: ElementBase, target: Class):
            """Build the target class extensions from the element children.

            Args:
                obj: The element base instance
                target: The target class instance
            """
            restrictions = obj.get_restrictions()
            extensions = [
                cls.build_class_extension(obj.class_name, target, base, restrictions)
                for base in obj.bases
            ]
            extensions.extend(cls.children_extensions(obj, target))
            target.extensions = collections.unique_sequence(extensions)

        @classmethod
        def build_attr_type(
            cls,
            target: Class,
            name: str,
            forward: bool = False,
        ) -> AttrType:
            """Create a reference attr type for the target class.

            Args:
                target: The target class instance
                name: the qualified name of the attr
                forward: Whether the reference is for an inner class

            Returns:
                The new attr type instance.
            """
            prefix, suffix = text.split(name)
            namespace = target.ns_map.get(prefix, target.target_namespace)
            qname = build_qname(namespace, suffix)
            datatype = DataType.from_qname(qname)

            return AttrType(
                qname=qname,
                native=datatype is not None,
                forward=forward,
            )

        @classmethod
        def element_children(
            cls,
            obj: ElementBase,
            parent_restrictions: Restrictions,
        ) -> Iterator[tuple[ElementBase, Restrictions]]:
            """Recursively find and return all child elements.

            Args:
                obj: The element base instance.
                parent_restrictions: The parent element restrictions instance

            Yields:
                An iterator of elements and their parent restrictions.
            """
            for child in obj.children():
                if child.is_property:
                    yield child, parent_restrictions
                else:
                    restrictions = Restrictions.from_element(child)
                    restrictions.merge(parent_restrictions)
                    yield from cls.element_children(child, restrictions)

        @classmethod
        def element_namespace(
            cls,
            obj: ElementBase,
            target_namespace: str | None,
        ) -> str | None:
            """Return the target namespace for the given schema element.

            Rules:
                - elements/attributes with specific target namespace
                - prefixed elements returns the namespace from schema ns_map
                - qualified elements returns the schema target namespace
                - unqualified elements return an empty string
                - unqualified attributes return None

            Args:
                obj: The element base instance
                target_namespace: The schema target namespace

            Returns:
                The element real namespace or None if no namespace
            """
            raw_namespace = obj.raw_namespace
            if raw_namespace:
                return raw_namespace

            prefix = obj.prefix
            if prefix:
                return obj.ns_map.get(prefix)

            if obj.is_qualified and (
                not obj.is_ref
                or not target_namespace
                or not prefix_exists(target_namespace, obj.ns_map)
                or is_default(target_namespace, obj.ns_map)
            ):
                return target_namespace

            return "" if isinstance(obj, Element) else None

        @classmethod
        def children_extensions(
            cls,
            obj: ElementBase,
            target: Class,
        ) -> Iterator[Extension]:
            """Recursively find and return all target's extension instances.

            Args:
                obj: The element base instance
                target: The target class instance

            Yields:
                An iterator of extension instances.
            """
            for child in obj.children():
                if child.is_property:
                    continue

                for ext in child.bases:
                    yield cls.build_class_extension(
                        child.class_name, target, ext, child.get_restrictions()
                    )

                yield from cls.children_extensions(child, target)

        @classmethod
        def build_class_extension(
            cls,
            tag: str,
            target: Class,
            name: str,
            restrictions: dict,
        ) -> Extension:
            """Create a reference extension for the target class.

            Args:
                tag: The tag name
                target: The target class instance
                name: The qualified name of the extension
                restrictions: A key-value restrictions mapping

            Returns:
                The new extension instance.
            """
            return Extension(
                type=cls.build_attr_type(target, name),
                tag=tag,
                restrictions=Restrictions(**restrictions),
            )

        @classmethod
        def build_class_attribute(
            cls,
            target: Class,
            obj: ElementBase,
            parent_restrictions: Restrictions,
        ):
            """Build and append a new attr to the target class.

            Args:
                target: The target class instance
                obj: The element base instance to map to an attr
                parent_restrictions: The parent element restrictions
            """
            target.ns_map.update(obj.ns_map)
            types = cls.build_attr_types(target, obj)
            restrictions = Restrictions.from_element(obj)

            if obj.class_name in (Tag.ELEMENT, Tag.ANY, Tag.GROUP):
                restrictions.merge(parent_restrictions)

            name = obj.real_name
            target.attrs.append(
                Attr(
                    index=obj.index,
                    name=name,
                    default=obj.default_value,
                    fixed=obj.is_fixed,
                    types=types,
                    tag=obj.class_name,
                    help=obj.display_help,
                    namespace=cls.element_namespace(obj, target.target_namespace),
                    restrictions=restrictions,
                )
            )

        @classmethod
        def build_attr_types(cls, target: Class, obj: ElementBase) -> list[AttrType]:
            """Convert the element types and inner types to an attr types.

            Args:
                target: The target class instance
                obj: The element base instance to extract the types from

            Returns:
                A list of attr type instances.
            """
            types = [cls.build_attr_type(target, tp) for tp in obj.attr_types]

            location = target.location
            namespace = target.target_namespace
            for inner in cls.build_inner_classes(obj, location, namespace):
                inner.parent = target
                target.inner.append(inner)
                types.append(AttrType(qname=inner.qname, forward=True))

            if not types:
                types.append(cls.build_attr_type(target, name=obj.default_type))

            return collections.unique_sequence(types)

        @classmethod
        def build_inner_classes(
            cls,
            obj: ElementBase,
            location: str,
            namespace: str | None,
        ) -> Iterator[Class]:
            """Find and convert anonymous types to a class instances.

            Args:
                obj: The element base instance
                location: The schema location
                namespace: The parent element namespace

            Yields:
                An iterator of class instances.
            """
            if isinstance(obj, SimpleType) and obj.is_enumeration:
                yield cls.build_class(obj, obj.class_name, location, namespace)
            else:
                for child in obj.children():
                    if isinstance(child, ComplexType) or (
                        isinstance(child, SimpleType) and child.is_enumeration
                    ):
                        child.name = obj.real_name
                        yield cls.build_class(child, obj.class_name, location, namespace)
                    else:
                        yield from cls.build_inner_classes(child, location, namespace)

#### `map(schema)` `classmethod`

Map schema children elements to classes.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`schema` | `Schema` | The schema instance | required

Returns:

Type | Description
--- | ---
`list[Class]` | A list of classes.

Source code in `xsdata/codegen/mappers/schema.py`

    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45

    @classmethod
    def map(cls, schema: Schema) -> list[Class]:
        """Map schema children elements to classes.

        Args:
            schema: The schema instance

        Returns:
            A list of classes.
        """
        assert schema.location is not None

        location = schema.location
        target_namespace = schema.target_namespace

        return [
            cls.build_class(element, container, location, target_namespace)
            for container, element in cls.root_elements(schema)
        ]

#### `root_elements(schema)` `classmethod`

Return the schema root elements.

Qualified Elements

- SimpleType
- ComplexType
- Group
- AttributeGroup
- Element
- Attribute

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`schema` | `Schema` | The schema instance | required

Yields:

Type | Description
--- | ---
`tuple[str, ElementBase]` | An iterator of element base instances.

Source code in `xsdata/codegen/mappers/schema.py`

    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 root_elements(cls, schema: Schema) -> Iterator[tuple[str, ElementBase]]:
        """Return the schema root elements.

        Qualified Elements:
            - SimpleType
            - ComplexType
            - Group
            - AttributeGroup
            - Element
            - Attribute

        Args:
            schema: The schema instance

        Yields:
            An iterator of element base instances.
        """

        def condition(item: ElementBase) -> bool:
            return isinstance(item, ROOT_CLASSES)

        for override in schema.overrides:
            for child in override.children(condition=condition):
                yield Tag.OVERRIDE, child

        for redefine in schema.redefines:
            for child in redefine.children(condition=condition):
                yield Tag.REDEFINE, child

        for child in schema.children(condition=condition):
            yield Tag.SCHEMA, child

#### `build_class(obj, container, location, target_namespace)` `classmethod`

Build and return a class instance.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`container` | `str` | The container name | required
`location` | `str` | The schema location | required
`target_namespace` | `str | None` | The schema target namespace | required

Returns:

Type | Description
--- | ---
`Class` | The new class instance.

Source code in `xsdata/codegen/mappers/schema.py`

     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117

    @classmethod
    def build_class(
        cls,
        obj: ElementBase,
        container: str,
        location: str,
        target_namespace: str | None,
    ) -> Class:
        """Build and return a class instance.

        Args:
            obj: The element base instance
            container: The container name
            location: The schema location
            target_namespace: The schema target namespace

        Returns:
            The new class instance.
        """
        instance = Class(
            qname=build_qname(target_namespace, obj.real_name),
            abstract=obj.is_abstract,
            namespace=cls.element_namespace(obj, target_namespace),
            mixed=obj.is_mixed,
            nillable=obj.is_nillable,
            tag=obj.class_name,
            container=container,
            help=obj.display_help,
            ns_map=obj.ns_map,
            location=location,
            default=obj.default_value,
            fixed=obj.is_fixed,
            substitutions=cls.build_substitutions(obj, target_namespace),
        )

        cls.build_class_extensions(obj, instance)
        cls.build_class_attributes(obj, instance)
        return instance

#### `build_substitutions(obj, target_namespace)` `classmethod`

Builds a list of qualified substitution group names.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`target_namespace` | `str | None` | The schema target namespace | required

Returns:

Type | Description
--- | ---
`list[str]` | A list of qualified substitution group names.

Source code in `xsdata/codegen/mappers/schema.py`

    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137

    @classmethod
    def build_substitutions(
        cls,
        obj: ElementBase,
        target_namespace: str | None,
    ) -> list[str]:
        """Builds a list of qualified substitution group names.

        Args:
            obj: The element base instance
            target_namespace: The schema target namespace

        Returns:
            A list of qualified substitution group names.
        """
        return [
            build_qname(obj.ns_map.get(prefix, target_namespace), suffix)
            for prefix, suffix in map(text.split, obj.substitutions)
        ]

#### `build_class_attributes(obj, target)` `classmethod`

Build the target class attrs from the element children.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`target` | `Class` | The target class instance | required

Source code in `xsdata/codegen/mappers/schema.py`

    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151

    @classmethod
    def build_class_attributes(cls, obj: ElementBase, target: Class):
        """Build the target class attrs from the element children.

        Args:
            obj: The element base instance
            target: The target class instance
        """
        base_restrictions = Restrictions.from_element(obj)
        for child, restrictions in cls.element_children(obj, base_restrictions):
            cls.build_class_attribute(target, child, restrictions)

        target.attrs.sort(key=lambda x: x.index)

#### `build_class_extensions(obj, target)` `classmethod`

Build the target class extensions from the element children.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`target` | `Class` | The target class instance | required

Source code in `xsdata/codegen/mappers/schema.py`

    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167

    @classmethod
    def build_class_extensions(cls, obj: ElementBase, target: Class):
        """Build the target class extensions from the element children.

        Args:
            obj: The element base instance
            target: The target class instance
        """
        restrictions = obj.get_restrictions()
        extensions = [
            cls.build_class_extension(obj.class_name, target, base, restrictions)
            for base in obj.bases
        ]
        extensions.extend(cls.children_extensions(obj, target))
        target.extensions = collections.unique_sequence(extensions)

#### `build_attr_type(target, name, forward=False)` `classmethod`

Create a reference attr type for the target class.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`target` | `Class` | The target class instance | required
`name` | `str` | the qualified name of the attr | required
`forward` | `bool` | Whether the reference is for an inner class | `False`

Returns:

Type | Description
--- | ---
`AttrType` | The new attr type instance.

Source code in `xsdata/codegen/mappers/schema.py`

    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195

    @classmethod
    def build_attr_type(
        cls,
        target: Class,
        name: str,
        forward: bool = False,
    ) -> AttrType:
        """Create a reference attr type for the target class.

        Args:
            target: The target class instance
            name: the qualified name of the attr
            forward: Whether the reference is for an inner class

        Returns:
            The new attr type instance.
        """
        prefix, suffix = text.split(name)
        namespace = target.ns_map.get(prefix, target.target_namespace)
        qname = build_qname(namespace, suffix)
        datatype = DataType.from_qname(qname)

        return AttrType(
            qname=qname,
            native=datatype is not None,
            forward=forward,
        )

#### `element_children(obj, parent_restrictions)` `classmethod`

Recursively find and return all child elements.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance. | required
`parent_restrictions` | `Restrictions` | The parent element restrictions instance | required

Yields:

Type | Description
--- | ---
`tuple[ElementBase, Restrictions]` | An iterator of elements and their parent restrictions.

Source code in `xsdata/codegen/mappers/schema.py`

    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218

    @classmethod
    def element_children(
        cls,
        obj: ElementBase,
        parent_restrictions: Restrictions,
    ) -> Iterator[tuple[ElementBase, Restrictions]]:
        """Recursively find and return all child elements.

        Args:
            obj: The element base instance.
            parent_restrictions: The parent element restrictions instance

        Yields:
            An iterator of elements and their parent restrictions.
        """
        for child in obj.children():
            if child.is_property:
                yield child, parent_restrictions
            else:
                restrictions = Restrictions.from_element(child)
                restrictions.merge(parent_restrictions)
                yield from cls.element_children(child, restrictions)

#### `element_namespace(obj, target_namespace)` `classmethod`

Return the target namespace for the given schema element.

Rules

- elements/attributes with specific target namespace
- prefixed elements returns the namespace from schema ns_map
- qualified elements returns the schema target namespace
- unqualified elements return an empty string
- unqualified attributes return None

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`target_namespace` | `str | None` | The schema target namespace | required

Returns:

Type | Description
--- | ---
`str | None` | The element real namespace or None if no namespace

Source code in `xsdata/codegen/mappers/schema.py`

    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258

    @classmethod
    def element_namespace(
        cls,
        obj: ElementBase,
        target_namespace: str | None,
    ) -> str | None:
        """Return the target namespace for the given schema element.

        Rules:
            - elements/attributes with specific target namespace
            - prefixed elements returns the namespace from schema ns_map
            - qualified elements returns the schema target namespace
            - unqualified elements return an empty string
            - unqualified attributes return None

        Args:
            obj: The element base instance
            target_namespace: The schema target namespace

        Returns:
            The element real namespace or None if no namespace
        """
        raw_namespace = obj.raw_namespace
        if raw_namespace:
            return raw_namespace

        prefix = obj.prefix
        if prefix:
            return obj.ns_map.get(prefix)

        if obj.is_qualified and (
            not obj.is_ref
            or not target_namespace
            or not prefix_exists(target_namespace, obj.ns_map)
            or is_default(target_namespace, obj.ns_map)
        ):
            return target_namespace

        return "" if isinstance(obj, Element) else None

#### `children_extensions(obj, target)` `classmethod`

Recursively find and return all target's extension instances.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`target` | `Class` | The target class instance | required

Yields:

Type | Description
--- | ---
`Extension` | An iterator of extension instances.

Source code in `xsdata/codegen/mappers/schema.py`

    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284

    @classmethod
    def children_extensions(
        cls,
        obj: ElementBase,
        target: Class,
    ) -> Iterator[Extension]:
        """Recursively find and return all target's extension instances.

        Args:
            obj: The element base instance
            target: The target class instance

        Yields:
            An iterator of extension instances.
        """
        for child in obj.children():
            if child.is_property:
                continue

            for ext in child.bases:
                yield cls.build_class_extension(
                    child.class_name, target, ext, child.get_restrictions()
                )

            yield from cls.children_extensions(child, target)

#### `build_class_extension(tag, target, name, restrictions)` `classmethod`

Create a reference extension for the target class.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`tag` | `str` | The tag name | required
`target` | `Class` | The target class instance | required
`name` | `str` | The qualified name of the extension | required
`restrictions` | `dict` | A key-value restrictions mapping | required

Returns:

Type | Description
--- | ---
`Extension` | The new extension instance.

Source code in `xsdata/codegen/mappers/schema.py`

    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309

    @classmethod
    def build_class_extension(
        cls,
        tag: str,
        target: Class,
        name: str,
        restrictions: dict,
    ) -> Extension:
        """Create a reference extension for the target class.

        Args:
            tag: The tag name
            target: The target class instance
            name: The qualified name of the extension
            restrictions: A key-value restrictions mapping

        Returns:
            The new extension instance.
        """
        return Extension(
            type=cls.build_attr_type(target, name),
            tag=tag,
            restrictions=Restrictions(**restrictions),
        )

#### `build_class_attribute(target, obj, parent_restrictions)` `classmethod`

Build and append a new attr to the target class.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`target` | `Class` | The target class instance | required
`obj` | `ElementBase` | The element base instance to map to an attr | required
`parent_restrictions` | `Restrictions` | The parent element restrictions | required

Source code in `xsdata/codegen/mappers/schema.py`

    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345

    @classmethod
    def build_class_attribute(
        cls,
        target: Class,
        obj: ElementBase,
        parent_restrictions: Restrictions,
    ):
        """Build and append a new attr to the target class.

        Args:
            target: The target class instance
            obj: The element base instance to map to an attr
            parent_restrictions: The parent element restrictions
        """
        target.ns_map.update(obj.ns_map)
        types = cls.build_attr_types(target, obj)
        restrictions = Restrictions.from_element(obj)

        if obj.class_name in (Tag.ELEMENT, Tag.ANY, Tag.GROUP):
            restrictions.merge(parent_restrictions)

        name = obj.real_name
        target.attrs.append(
            Attr(
                index=obj.index,
                name=name,
                default=obj.default_value,
                fixed=obj.is_fixed,
                types=types,
                tag=obj.class_name,
                help=obj.display_help,
                namespace=cls.element_namespace(obj, target.target_namespace),
                restrictions=restrictions,
            )
        )

#### `build_attr_types(target, obj)` `classmethod`

Convert the element types and inner types to an attr types.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`target` | `Class` | The target class instance | required
`obj` | `ElementBase` | The element base instance to extract the types from | required

Returns:

Type | Description
--- | ---
`list[AttrType]` | A list of attr type instances.

Source code in `xsdata/codegen/mappers/schema.py`

    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370

    @classmethod
    def build_attr_types(cls, target: Class, obj: ElementBase) -> list[AttrType]:
        """Convert the element types and inner types to an attr types.

        Args:
            target: The target class instance
            obj: The element base instance to extract the types from

        Returns:
            A list of attr type instances.
        """
        types = [cls.build_attr_type(target, tp) for tp in obj.attr_types]

        location = target.location
        namespace = target.target_namespace
        for inner in cls.build_inner_classes(obj, location, namespace):
            inner.parent = target
            target.inner.append(inner)
            types.append(AttrType(qname=inner.qname, forward=True))

        if not types:
            types.append(cls.build_attr_type(target, name=obj.default_type))

        return collections.unique_sequence(types)

#### `build_inner_classes(obj, location, namespace)` `classmethod`

Find and convert anonymous types to a class instances.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`obj` | `ElementBase` | The element base instance | required
`location` | `str` | The schema location | required
`namespace` | `str | None` | The parent element namespace | required

Yields:

Type | Description
--- | ---
`Class` | An iterator of class instances.

Source code in `xsdata/codegen/mappers/schema.py`

    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399

    @classmethod
    def build_inner_classes(
        cls,
        obj: ElementBase,
        location: str,
        namespace: str | None,
    ) -> Iterator[Class]:
        """Find and convert anonymous types to a class instances.

        Args:
            obj: The element base instance
            location: The schema location
            namespace: The parent element namespace

        Yields:
            An iterator of class instances.
        """
        if isinstance(obj, SimpleType) and obj.is_enumeration:
            yield cls.build_class(obj, obj.class_name, location, namespace)
        else:
            for child in obj.children():
                if isinstance(child, ComplexType) or (
                    isinstance(child, SimpleType) and child.is_enumeration
                ):
                    child.name = obj.real_name
                    yield cls.build_class(child, obj.class_name, location, namespace)
                else:
                    yield from cls.build_inner_classes(child, location, namespace)