Skip to content

models

xsdata.codegen.models

Restrictions dataclass

Class field validation restrictions.

Parameters:

Name Type Description Default
min_occurs Optional[int]

The minimum number of occurrences

field(default=None)
max_occurs Optional[int]

The maximum number of occurrences

field(default=None)
min_exclusive Optional[str]

The lower exclusive bound for numeric values

field(default=None)
min_inclusive Optional[str]

The lower inclusive bound for numeric values

field(default=None)
min_length Optional[int]

The minimum length of characters or list items allowed

field(default=None)
max_exclusive Optional[str]

The upper exclusive bound for numeric values

field(default=None)
max_inclusive Optional[str]

The upper inclusive bound for numeric values

field(default=None)
max_length Optional[int]

The max length of characters or list items allowed

field(default=None)
total_digits Optional[int]

The exact number of digits allowed for numeric values

field(default=None)
fraction_digits Optional[int]

The maximum number of decimal places allowed

field(default=None)
length Optional[int]

The exact number of characters or list items allowed

field(default=None)
white_space Optional[str]

Specifies how white space is handled

field(default=None)
pattern Optional[str]

Defines the exact sequence of characters that are acceptable

field(default=None)
explicit_timezone Optional[str]

Require or prohibit the time zone offset in date/time

field(default=None)
nillable Optional[bool]

Specifies whether nil content is allowed

field(default=None)
sequence Optional[int]

The sequence reference number of the attr

field(default=None)
tokens Optional[bool]

Specifies whether the value needs tokenization

field(default=None)
format Optional[str]

The output format used for byte and datetime types

field(default=None)
choice Optional[int]

The choice reference number of the attr

field(default=None)
group Optional[int]

The group reference number of the attr

field(default=None)
process_contents Optional[str]

Specifies the content processed mode: strict, lax, skip

field(default=None)
path List[Tuple[str, int, int, int]]

The coded attr path in the source document

field(default_factory=list)
Source code in xsdata/codegen/models.py
 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
@dataclass
class Restrictions:
    """Class field validation restrictions.

    Args:
        min_occurs: The minimum number of occurrences
        max_occurs: The maximum number of occurrences
        min_exclusive: The lower exclusive bound for numeric values
        min_inclusive: The lower inclusive bound for numeric values
        min_length: The minimum length of characters or list items allowed
        max_exclusive: The upper exclusive bound for numeric values
        max_inclusive: The upper inclusive bound for numeric values
        max_length: The max length of characters or list items allowed
        total_digits:  The exact number of digits allowed for numeric values
        fraction_digits: The maximum number of decimal places allowed
        length: The exact number of characters or list items allowed
        white_space: Specifies how white space is handled
        pattern: Defines the exact sequence of characters that are acceptable
        explicit_timezone: Require or prohibit the time zone offset in date/time
        nillable: Specifies whether nil content is allowed
        sequence: The sequence reference number of the attr
        tokens: Specifies whether the value needs tokenization
        format: The output format used for byte and datetime types
        choice: The choice reference number of the attr
        group: The group reference number of the attr
        process_contents: Specifies the content processed mode: strict, lax, skip
        path: The coded attr path in the source document
    """

    min_occurs: Optional[int] = field(default=None)
    max_occurs: Optional[int] = field(default=None)
    min_exclusive: Optional[str] = field(default=None)
    min_inclusive: Optional[str] = field(default=None)
    min_length: Optional[int] = field(default=None)
    max_exclusive: Optional[str] = field(default=None)
    max_inclusive: Optional[str] = field(default=None)
    max_length: Optional[int] = field(default=None)
    total_digits: Optional[int] = field(default=None)
    fraction_digits: Optional[int] = field(default=None)
    length: Optional[int] = field(default=None)
    white_space: Optional[str] = field(default=None)
    pattern: Optional[str] = field(default=None)
    explicit_timezone: Optional[str] = field(default=None)
    nillable: Optional[bool] = field(default=None)
    sequence: Optional[int] = field(default=None)
    tokens: Optional[bool] = field(default=None)
    format: Optional[str] = field(default=None)
    choice: Optional[int] = field(default=None)
    group: Optional[int] = field(default=None)
    process_contents: Optional[str] = field(default=None)
    path: List[Tuple[str, int, int, int]] = field(default_factory=list)

    @property
    def is_list(self) -> bool:
        """Return whether the max occurs larger than one."""
        return self.max_occurs is not None and self.max_occurs > 1

    @property
    def is_optional(self) -> bool:
        """Return whether the min occurs is zero."""
        return self.min_occurs == 0

    @property
    def is_prohibited(self) -> bool:
        """Return whether the max occurs is zero."""
        return self.max_occurs == 0

    def merge(self, source: "Restrictions"):
        """Update properties from another instance.

        Args:
            source: The source instance to merge properties from
        """
        keys = (
            "min_exclusive",
            "min_inclusive",
            "min_length",
            "max_exclusive",
            "max_inclusive",
            "max_length",
            "total_digits",
            "fraction_digits",
            "length",
            "white_space",
            "pattern",
            "explicit_timezone",
            "process_contents",
        )

        for key in keys:
            value = getattr(source, key)
            if value is not None:
                setattr(self, key, value)

        self.path = source.path + self.path
        self.sequence = self.sequence or source.sequence
        self.choice = self.choice or source.choice
        self.tokens = self.tokens or source.tokens
        self.format = self.format or source.format
        self.group = self.group or source.group

        if self.min_occurs is None and source.min_occurs is not None:
            self.min_occurs = source.min_occurs

        if self.max_occurs is None and source.max_occurs is not None:
            self.max_occurs = source.max_occurs

    def asdict(self, types: Optional[List[Type]] = None) -> Dict:
        """Return the initialized only properties as a dictionary.

        Skip None or implied values, and optionally use the
        attribute types to convert relevant options.

        Args:
            types: An optional list of attr python types

        Returns:
            A key-value of map of the attr restrictions for generation.
        """
        result = {}
        sorted_types = converter.sort_types(types) if types else []

        if self.is_list:
            if self.min_occurs is not None and self.min_occurs > 0:
                result["min_occurs"] = self.min_occurs
            if self.max_occurs is not None and self.max_occurs < sys.maxsize:
                result["max_occurs"] = self.max_occurs
        elif self.min_occurs == self.max_occurs == 1 and not self.nillable:
            result["required"] = True

        for key, value in asdict(self).items():
            if value is None or key in (
                "choice",
                "group",
                "min_occurs",
                "max_occurs",
                "path",
            ):
                continue

            if key == "process_contents" and value != "skip":
                continue

            if key.endswith("clusive") and types:
                value = converter.deserialize(value, sorted_types)

            result[key] = value

        return result

    def clone(self) -> "Restrictions":
        """Return a deep cloned instance."""
        return replace(self)

    @classmethod
    def from_element(cls, element: ElementBase) -> "Restrictions":
        """Static constructor from a xsd model.

        Args:
            element: A element base instance.

        Returns:
            The new restrictions instance
        """
        return cls(**element.get_restrictions())

is_list: bool property

Return whether the max occurs larger than one.

is_optional: bool property

Return whether the min occurs is zero.

is_prohibited: bool property

Return whether the max occurs is zero.

merge(source)

Update properties from another instance.

Parameters:

Name Type Description Default
source Restrictions

The source instance to merge properties from

required
Source code in xsdata/codegen/models.py
 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
def merge(self, source: "Restrictions"):
    """Update properties from another instance.

    Args:
        source: The source instance to merge properties from
    """
    keys = (
        "min_exclusive",
        "min_inclusive",
        "min_length",
        "max_exclusive",
        "max_inclusive",
        "max_length",
        "total_digits",
        "fraction_digits",
        "length",
        "white_space",
        "pattern",
        "explicit_timezone",
        "process_contents",
    )

    for key in keys:
        value = getattr(source, key)
        if value is not None:
            setattr(self, key, value)

    self.path = source.path + self.path
    self.sequence = self.sequence or source.sequence
    self.choice = self.choice or source.choice
    self.tokens = self.tokens or source.tokens
    self.format = self.format or source.format
    self.group = self.group or source.group

    if self.min_occurs is None and source.min_occurs is not None:
        self.min_occurs = source.min_occurs

    if self.max_occurs is None and source.max_occurs is not None:
        self.max_occurs = source.max_occurs

asdict(types=None)

Return the initialized only properties as a dictionary.

Skip None or implied values, and optionally use the attribute types to convert relevant options.

Parameters:

Name Type Description Default
types Optional[List[Type]]

An optional list of attr python types

None

Returns:

Type Description
Dict

A key-value of map of the attr restrictions for generation.

Source code in xsdata/codegen/models.py
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
def asdict(self, types: Optional[List[Type]] = None) -> Dict:
    """Return the initialized only properties as a dictionary.

    Skip None or implied values, and optionally use the
    attribute types to convert relevant options.

    Args:
        types: An optional list of attr python types

    Returns:
        A key-value of map of the attr restrictions for generation.
    """
    result = {}
    sorted_types = converter.sort_types(types) if types else []

    if self.is_list:
        if self.min_occurs is not None and self.min_occurs > 0:
            result["min_occurs"] = self.min_occurs
        if self.max_occurs is not None and self.max_occurs < sys.maxsize:
            result["max_occurs"] = self.max_occurs
    elif self.min_occurs == self.max_occurs == 1 and not self.nillable:
        result["required"] = True

    for key, value in asdict(self).items():
        if value is None or key in (
            "choice",
            "group",
            "min_occurs",
            "max_occurs",
            "path",
        ):
            continue

        if key == "process_contents" and value != "skip":
            continue

        if key.endswith("clusive") and types:
            value = converter.deserialize(value, sorted_types)

        result[key] = value

    return result

clone()

Return a deep cloned instance.

Source code in xsdata/codegen/models.py
176
177
178
def clone(self) -> "Restrictions":
    """Return a deep cloned instance."""
    return replace(self)

from_element(element) classmethod

Static constructor from a xsd model.

Parameters:

Name Type Description Default
element ElementBase

A element base instance.

required

Returns:

Type Description
Restrictions

The new restrictions instance

Source code in xsdata/codegen/models.py
180
181
182
183
184
185
186
187
188
189
190
@classmethod
def from_element(cls, element: ElementBase) -> "Restrictions":
    """Static constructor from a xsd model.

    Args:
        element: A element base instance.

    Returns:
        The new restrictions instance
    """
    return cls(**element.get_restrictions())

AttrType dataclass

Class field typing information.

Parameters:

Name Type Description Default
qname str

The namespace qualified name

required
alias Optional[str]

The type alias

field(default=None, compare=False)
reference int

The type reference number

field(default=0, compare=False)
native bool

Specifies if it's python native type

field(default=False)
forward bool

Specifies if it's a forward reference

field(default=False)
circular bool

Specifies if it's a circular reference

field(default=False)
substituted bool

Specifies if it has been processed for substitution groups

field(default=False, compare=False)
Source code in xsdata/codegen/models.py
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
@dataclass(unsafe_hash=True)
class AttrType:
    """Class field typing information.

    Args:
        qname: The namespace qualified name
        alias: The type alias
        reference: The type reference number
        native: Specifies if it's python native type
        forward: Specifies if it's a forward reference
        circular: Specifies if it's a circular reference
        substituted: Specifies if it has been processed for substitution groups
    """

    qname: str
    alias: Optional[str] = field(default=None, compare=False)
    reference: int = field(default=0, compare=False)
    native: bool = field(default=False)
    forward: bool = field(default=False)
    circular: bool = field(default=False)
    substituted: bool = field(default=False, compare=False)

    @property
    def datatype(self) -> Optional[DataType]:
        """Return the datatype instance if native, none otherwise."""
        return DataType.from_qname(self.qname) if self.native else None

    @property
    def name(self) -> str:
        """Shortcut for qname local name."""
        return namespaces.local_name(self.qname)

    def is_dependency(self, allow_circular: bool) -> bool:
        """Return whether this type is a dependency.

        The type must a reference to a user type, not a forward
        reference and not a circular unless if it's allowed.

        Args:
            allow_circular: Allow circular references as dependencies

        Returns:
            The bool result/
        """
        return not (
            self.forward or self.native or (not allow_circular and self.circular)
        )

    def clone(self) -> "AttrType":
        """Return a deep cloned instance."""
        return replace(self)

datatype: Optional[DataType] property

Return the datatype instance if native, none otherwise.

name: str property

Shortcut for qname local name.

is_dependency(allow_circular)

Return whether this type is a dependency.

The type must a reference to a user type, not a forward reference and not a circular unless if it's allowed.

Parameters:

Name Type Description Default
allow_circular bool

Allow circular references as dependencies

required

Returns:

Type Description
bool

The bool result/

Source code in xsdata/codegen/models.py
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
def is_dependency(self, allow_circular: bool) -> bool:
    """Return whether this type is a dependency.

    The type must a reference to a user type, not a forward
    reference and not a circular unless if it's allowed.

    Args:
        allow_circular: Allow circular references as dependencies

    Returns:
        The bool result/
    """
    return not (
        self.forward or self.native or (not allow_circular and self.circular)
    )

clone()

Return a deep cloned instance.

Source code in xsdata/codegen/models.py
241
242
243
def clone(self) -> "AttrType":
    """Return a deep cloned instance."""
    return replace(self)

Attr dataclass

Class field model representation.

Parameters:

Name Type Description Default
tag str

The xml tag that produced this attr

required
name str

The final attr name

field(compare=False)
local_name str

The original attr name

field(init=False)
index int

The index position of this attr in the class

field(compare=False, default_factory=int)
default Optional[str]

The default value

field(default=None, compare=False)
fixed bool

Specifies if the default value is fixed

field(default=False, compare=False)
mixed bool

Specifies if the attr supports mixed content

field(default=False, compare=False)
types List[AttrType]

The attr types list

field(default_factory=list, compare=False)
choices List[Attr]

The attr choice list

field(default_factory=list, compare=False)
namespace Optional[str]

The attr namespace

field(default=None)
help Optional[str]

The attr help text

field(default=None, compare=False)
restrictions Restrictions

The attr restrictions instance

field(default_factory=Restrictions, compare=False)
parent Optional[Class]

The class reference of the attr

field(default=None, compare=False)
substitution Optional[str]

The substitution group this attr belongs to

field(default=None, compare=False)
Source code in xsdata/codegen/models.py
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
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
@dataclass
class Attr:
    """Class field model representation.

    Args:
        tag: The xml tag that produced this attr
        name: The final attr name
        local_name: The original attr name
        index: The index position of this attr in the class
        default: The default value
        fixed: Specifies if the default value is fixed
        mixed: Specifies if the attr supports mixed content
        types: The attr types list
        choices: The attr choice list
        namespace: The attr namespace
        help: The attr help text
        restrictions: The attr restrictions instance
        parent: The class reference of the attr
        substitution: The substitution group this attr belongs to
    """

    tag: str
    name: str = field(compare=False)
    local_name: str = field(init=False)
    index: int = field(compare=False, default_factory=int)
    default: Optional[str] = field(default=None, compare=False)
    fixed: bool = field(default=False, compare=False)
    mixed: bool = field(default=False, compare=False)
    types: List[AttrType] = field(default_factory=list, compare=False)
    choices: List["Attr"] = field(default_factory=list, compare=False)
    namespace: Optional[str] = field(default=None)
    help: Optional[str] = field(default=None, compare=False)
    restrictions: Restrictions = field(default_factory=Restrictions, compare=False)
    parent: Optional["Class"] = field(default=None, compare=False)
    substitution: Optional[str] = field(default=None, compare=False)

    def __post_init__(self):
        """Set the original attr name on init."""
        self.local_name = self.name

    @property
    def key(self) -> str:
        """Generate a key for this attr.

        Concatenate the tag/namespace/local_name.
        This key is used to find duplicates, it's not
        supposed to be unique.

        Returns:
            The unique key for this attr.

        """
        return f"{self.tag}.{self.namespace}.{self.local_name}"

    @property
    def is_attribute(self) -> bool:
        """Return whether this attr represents a xml attribute node."""
        return self.tag in (Tag.ATTRIBUTE, Tag.ANY_ATTRIBUTE)

    @property
    def is_enumeration(self) -> bool:
        """Return whether this attr an enumeration member."""
        return self.tag == Tag.ENUMERATION

    @property
    def is_dict(self) -> bool:
        """Return whether this attr is derived from xs:anyAttribute."""
        return self.tag == Tag.ANY_ATTRIBUTE

    @property
    def is_factory(self) -> bool:
        """Return whether this attribute is a list of items or a mapping."""
        return self.is_list or self.is_dict or self.is_tokens

    @property
    def is_forward_ref(self) -> bool:
        """Return whether any attr types is a forward or circular reference."""
        return any(tp.circular or tp.forward for tp in self.types)

    @property
    def is_group(self) -> bool:
        """Return whether this attr is a reference to a group class."""
        return self.tag in (Tag.ATTRIBUTE_GROUP, Tag.GROUP)

    @property
    def is_list(self) -> bool:
        """Return whether this attr requires a list of values."""
        return self.restrictions.is_list

    @property
    def is_prohibited(self) -> bool:
        """Return whether this attr is prohibited."""
        return self.restrictions.is_prohibited

    @property
    def is_nameless(self) -> bool:
        """Return whether this attr is a real xml node."""
        return self.tag not in (Tag.ATTRIBUTE, Tag.ELEMENT)

    @property
    def is_nillable(self) -> bool:
        """Return whether this attr supports nil values."""
        return self.restrictions.nillable is True

    @property
    def is_optional(self) -> bool:
        """Return whether this attr is not required."""
        return self.restrictions.is_optional

    @property
    def is_suffix(self) -> bool:
        """Return whether this attr is supposed to be generated last."""
        return self.index == sys.maxsize

    @property
    def is_xsi_type(self) -> bool:
        """Return whether this attr represents a xsi:type attribute."""
        return self.namespace == Namespace.XSI.uri and self.name == "type"

    @property
    def is_tokens(self) -> bool:
        """Return whether this attr supports token values."""
        return self.restrictions.tokens is True

    @property
    def is_wildcard(self) -> bool:
        """Return whether this attr supports any content."""
        return self.tag in (Tag.ANY_ATTRIBUTE, Tag.ANY)

    @property
    def is_any_type(self) -> bool:
        """Return whether this attr types support any content."""
        return any(tp is object for tp in self.get_native_types())

    @property
    def native_types(self) -> List[Type]:
        """Return a list of all the builtin data types."""
        return list(set(self.get_native_types()))

    @property
    def user_types(self) -> Iterator[AttrType]:
        """Yield an iterator of all the user defined types."""
        for tp in self.types:
            if not tp.native:
                yield tp

    @property
    def slug(self) -> str:
        """Return the slugified name of the attr."""
        return text.alnum(self.name)

    @property
    def xml_type(self) -> Optional[str]:
        """Return the xml type this attribute is mapped to."""
        return xml_type_map.get(self.tag)

    def clone(self) -> "Attr":
        """Return a deep cloned instance."""
        return replace(
            self,
            types=[x.clone() for x in self.types],
            restrictions=self.restrictions.clone(),
        )

    def get_native_types(self) -> Iterator[Type]:
        """Yield an iterator of all the native attr types."""
        for tp in self.types:
            datatype = tp.datatype
            if datatype:
                yield datatype.type

    def can_be_restricted(self) -> bool:
        """Return whether this attr can be restricted."""
        return self.xml_type not in (Tag.ATTRIBUTE, None)

key: str property

Generate a key for this attr.

Concatenate the tag/namespace/local_name. This key is used to find duplicates, it's not supposed to be unique.

Returns:

Type Description
str

The unique key for this attr.

is_attribute: bool property

Return whether this attr represents a xml attribute node.

is_enumeration: bool property

Return whether this attr an enumeration member.

is_dict: bool property

Return whether this attr is derived from xs:anyAttribute.

is_factory: bool property

Return whether this attribute is a list of items or a mapping.

is_forward_ref: bool property

Return whether any attr types is a forward or circular reference.

is_group: bool property

Return whether this attr is a reference to a group class.

is_list: bool property

Return whether this attr requires a list of values.

is_prohibited: bool property

Return whether this attr is prohibited.

is_nameless: bool property

Return whether this attr is a real xml node.

is_nillable: bool property

Return whether this attr supports nil values.

is_optional: bool property

Return whether this attr is not required.

is_suffix: bool property

Return whether this attr is supposed to be generated last.

is_xsi_type: bool property

Return whether this attr represents a xsi:type attribute.

is_tokens: bool property

Return whether this attr supports token values.

is_wildcard: bool property

Return whether this attr supports any content.

is_any_type: bool property

Return whether this attr types support any content.

native_types: List[Type] property

Return a list of all the builtin data types.

user_types: Iterator[AttrType] property

Yield an iterator of all the user defined types.

slug: str property

Return the slugified name of the attr.

xml_type: Optional[str] property

Return the xml type this attribute is mapped to.

__post_init__()

Set the original attr name on init.

Source code in xsdata/codegen/models.py
282
283
284
def __post_init__(self):
    """Set the original attr name on init."""
    self.local_name = self.name

clone()

Return a deep cloned instance.

Source code in xsdata/codegen/models.py
402
403
404
405
406
407
408
def clone(self) -> "Attr":
    """Return a deep cloned instance."""
    return replace(
        self,
        types=[x.clone() for x in self.types],
        restrictions=self.restrictions.clone(),
    )

get_native_types()

Yield an iterator of all the native attr types.

Source code in xsdata/codegen/models.py
410
411
412
413
414
415
def get_native_types(self) -> Iterator[Type]:
    """Yield an iterator of all the native attr types."""
    for tp in self.types:
        datatype = tp.datatype
        if datatype:
            yield datatype.type

can_be_restricted()

Return whether this attr can be restricted.

Source code in xsdata/codegen/models.py
417
418
419
def can_be_restricted(self) -> bool:
    """Return whether this attr can be restricted."""
    return self.xml_type not in (Tag.ATTRIBUTE, None)

Extension dataclass

Base class model representation.

Parameters:

Name Type Description Default
tag str

The xml tag that produced this extension

required
type AttrType

The extension type

required
restrictions Restrictions

The extension restrictions instance

field(hash=False)
Source code in xsdata/codegen/models.py
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
@dataclass(unsafe_hash=True)
class Extension:
    """Base class model representation.

    Args:
        tag: The xml tag that produced this extension
        type: The extension type
        restrictions: The extension restrictions instance
    """

    tag: str
    type: AttrType
    restrictions: Restrictions = field(hash=False)

    def clone(self) -> "Extension":
        """Return a deep cloned instance."""
        return replace(
            self,
            type=self.type.clone(),
            restrictions=self.restrictions.clone(),
        )

clone()

Return a deep cloned instance.

Source code in xsdata/codegen/models.py
436
437
438
439
440
441
442
def clone(self) -> "Extension":
    """Return a deep cloned instance."""
    return replace(
        self,
        type=self.type.clone(),
        restrictions=self.restrictions.clone(),
    )

Status

Bases: IntEnum

Class process status enumeration.

Source code in xsdata/codegen/models.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
class Status(IntEnum):
    """Class process status enumeration."""

    RAW = 0
    UNGROUPING = 10
    UNGROUPED = 11
    FLATTENING = 20
    FLATTENED = 21
    SANITIZING = 30
    SANITIZED = 31
    RESOLVING = 40
    RESOLVED = 41
    FINALIZING = 50
    FINALIZED = 51

Class dataclass

Class model representation.

Parameters:

Name Type Description Default
qname str

The namespace qualified name

required
tag str

The xml tag that produced this class

required
location str

The schema/document location uri

required
mixed bool

Specifies whether this class supports mixed content

field(default=False)
abstract bool

Specifies whether this is an abstract class

field(default=False)
nillable bool

Specifies whether this class supports nil content

field(default=False)
local_type bool

Specifies if this class was an inner type at some point

field(default=False)
status Status

The processing status of the class

field(default=RAW)
container Optional[str]

The xml container of the class, schema, override, redefine

field(default=None)
package Optional[str]

The designated package of the class

field(default=None)
module Optional[str]

The designated module of the class

field(default=None)
namespace Optional[str]

The class namespace

field(default=None)
help Optional[str]

The help text

field(default=None)
meta_name Optional[str]

The xml element name of the class

field(default=None)
default Any

The default value

field(default=None, compare=False)
fixed bool

Specifies whether the default value is fixed

field(default=False, compare=False)
substitutions List[str]

The list of all the substitution groups this class belongs to

field(default_factory=list)
extensions List[Extension]

The list of all the extension instances

field(default_factory=list)
attrs List[Attr]

The list of all the attr instances

field(default_factory=list)
inner List[Class]

The list of all the inner class instances

field(default_factory=list)
ns_map Dict

The namespace prefix-URI map

field(default_factory=dict)
Source code in xsdata/codegen/models.py
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
@dataclass
class Class:
    """Class model representation.

    Args:
        qname: The namespace qualified name
        tag: The xml tag that produced this class
        location: The schema/document location uri
        mixed: Specifies whether this class supports mixed content
        abstract: Specifies whether this is an abstract class
        nillable: Specifies whether this class supports nil content
        local_type: Specifies if this class was an inner type at some point
        status: The processing status of the class
        container: The xml container of the class, schema, override, redefine
        package: The designated package of the class
        module: The designated module of the class
        namespace: The class namespace
        help: The help text
        meta_name: The xml element name of the class
        default: The default value
        fixed: Specifies whether the default value is fixed
        substitutions: The list of all the substitution groups this class belongs to
        extensions: The list of all the extension instances
        attrs: The list of all the attr instances
        inner: The list of all the inner class instances
        ns_map: The namespace prefix-URI map
    """

    qname: str
    tag: str
    location: str
    mixed: bool = field(default=False)
    abstract: bool = field(default=False)
    nillable: bool = field(default=False)
    local_type: bool = field(default=False)
    status: Status = field(default=Status.RAW)
    container: Optional[str] = field(default=None)
    package: Optional[str] = field(default=None)
    module: Optional[str] = field(default=None)
    namespace: Optional[str] = field(default=None)
    help: Optional[str] = field(default=None)
    meta_name: Optional[str] = field(default=None)
    default: Any = field(default=None, compare=False)
    fixed: bool = field(default=False, compare=False)
    substitutions: List[str] = field(default_factory=list)
    extensions: List[Extension] = field(default_factory=list)
    attrs: List[Attr] = field(default_factory=list)
    inner: List["Class"] = field(default_factory=list)
    ns_map: Dict = field(default_factory=dict)

    @property
    def name(self) -> str:
        """Shortcut for the class local name."""
        return namespaces.local_name(self.qname)

    @property
    def slug(self) -> str:
        """Return a slugified version of the class name."""
        return text.alnum(self.name)

    @property
    def ref(self) -> int:
        """Return this id reference of this instance."""
        return id(self)

    @property
    def target_namespace(self) -> Optional[str]:
        """Return the class target namespace."""
        return namespaces.target_uri(self.qname)

    @property
    def has_suffix_attr(self) -> bool:
        """Return whether it includes a suffix attr."""
        return any(attr.is_suffix for attr in self.attrs)

    @property
    def has_help_attr(self) -> bool:
        """Return whether at least one of attrs has help content."""
        return any(attr.help and attr.help.strip() for attr in self.attrs)

    @property
    def is_complex(self) -> bool:
        """Return whether class represents a xs:element/complex type."""
        return self.tag in (Tag.ELEMENT, Tag.COMPLEX_TYPE)

    @property
    def is_element(self) -> bool:
        """Return whether this class represents a xml element."""
        return self.tag == Tag.ELEMENT

    @property
    def is_enumeration(self) -> bool:
        """Return whether all attrs are enumeration members."""
        return len(self.attrs) > 0 and all(attr.is_enumeration for attr in self.attrs)

    @property
    def is_global_type(self) -> bool:
        """Return whether this class represents a root/global class.

        Global classes are the only classes that get generated by default.
        """
        return (not self.abstract and self.tag in GLOBAL_TYPES) or (
            self.tag == Tag.COMPLEX_TYPE and not self.is_simple_type
        )

    @property
    def is_group(self) -> bool:
        """Return whether this class is derived from a xs:group/attributeGroup."""
        return self.tag in (Tag.ATTRIBUTE_GROUP, Tag.GROUP)

    @property
    def is_nillable(self) -> bool:
        """Return whether this class represents a nillable xml element."""
        return self.nillable or any(x.restrictions.nillable for x in self.extensions)

    @property
    def is_mixed(self) -> bool:
        """Return whether this class supports mixed content."""
        return self.mixed or any(x.mixed for x in self.attrs)

    @property
    def is_restricted(self) -> bool:
        """Return whether this class includes any restriction extensions."""
        return any(
            True for extension in self.extensions if extension.tag == Tag.RESTRICTION
        )

    @property
    def is_service(self) -> bool:
        """Return whether this instance is derived from a wsdl:operation."""
        return self.tag == Tag.BINDING_OPERATION

    @property
    def is_simple_type(self) -> bool:
        """Return whether the class represents a simple type.

        Simple Types:
            - xs:simpleType/extension/list/union
            - have only one attr
            - have no extensions.
        """
        return (
            len(self.attrs) == 1
            and self.attrs[0].tag in SIMPLE_TYPES
            and not self.extensions
        )

    @property
    def references(self) -> Iterator[int]:
        """Yield all class object reference numbers."""

        def all_refs():
            for ext in self.extensions:
                yield ext.type.reference

            for attr in self.attrs:
                for tp in attr.types:
                    yield tp.reference

                for choice in attr.choices:
                    for ctp in choice.types:
                        yield ctp.reference

            for inner in self.inner:
                yield from inner.references

        for ref in all_refs():
            if ref:
                yield ref

    @property
    def target_module(self) -> str:
        """Return the designated full module path.

        Raises:
            CodeGenerationError: if the target was not designated
                a package and module.
        """
        if self.package and self.module:
            return f"{self.package}.{self.module}"

        if self.module:
            return self.module

        raise CodeGenerationError(
            f"Class `{self.name}` has not been assigned to a module yet!"
        )

    def clone(self) -> "Class":
        """Return a deep cloned instance."""
        inners = [inner.clone() for inner in self.inner]
        extensions = [extension.clone() for extension in self.extensions]
        attrs = [attr.clone() for attr in self.attrs]
        return replace(self, inner=inners, extensions=extensions, attrs=attrs)

    def dependencies(self, allow_circular: bool = False) -> Iterator[str]:
        """Yields all class dependencies.

        Omit circular and forward references by default.

        Collect:
            * base classes
            * attribute types
            * attribute choice types
            * recursively go through the inner classes
            * Ignore inner class references
            * Ignore native types.

        Args:
            allow_circular: Allow circular references
        """
        types = {ext.type for ext in self.extensions}

        for attr in self.attrs:
            types.update(attr.types)
            types.update(tp for choice in attr.choices for tp in choice.types)

        for tp in types:
            if tp.is_dependency(allow_circular):
                yield tp.qname

        for inner in self.inner:
            yield from inner.dependencies(allow_circular)

    def has_forward_ref(self) -> bool:
        """Return whether this class has any forward references."""
        for attr in self.attrs:
            if attr.is_forward_ref:
                return True

            if any(choice for choice in attr.choices if choice.is_forward_ref):
                return True

        return any(inner.has_forward_ref() for inner in self.inner)

name: str property

Shortcut for the class local name.

slug: str property

Return a slugified version of the class name.

ref: int property

Return this id reference of this instance.

target_namespace: Optional[str] property

Return the class target namespace.

has_suffix_attr: bool property

Return whether it includes a suffix attr.

has_help_attr: bool property

Return whether at least one of attrs has help content.

is_complex: bool property

Return whether class represents a xs:element/complex type.

is_element: bool property

Return whether this class represents a xml element.

is_enumeration: bool property

Return whether all attrs are enumeration members.

is_global_type: bool property

Return whether this class represents a root/global class.

Global classes are the only classes that get generated by default.

is_group: bool property

Return whether this class is derived from a xs:group/attributeGroup.

is_nillable: bool property

Return whether this class represents a nillable xml element.

is_mixed: bool property

Return whether this class supports mixed content.

is_restricted: bool property

Return whether this class includes any restriction extensions.

is_service: bool property

Return whether this instance is derived from a wsdl:operation.

is_simple_type: bool property

Return whether the class represents a simple type.

Simple Types
  • xs:simpleType/extension/list/union
  • have only one attr
  • have no extensions.

references: Iterator[int] property

Yield all class object reference numbers.

target_module: str property

Return the designated full module path.

Raises:

Type Description
CodeGenerationError

if the target was not designated a package and module.

clone()

Return a deep cloned instance.

Source code in xsdata/codegen/models.py
649
650
651
652
653
654
def clone(self) -> "Class":
    """Return a deep cloned instance."""
    inners = [inner.clone() for inner in self.inner]
    extensions = [extension.clone() for extension in self.extensions]
    attrs = [attr.clone() for attr in self.attrs]
    return replace(self, inner=inners, extensions=extensions, attrs=attrs)

dependencies(allow_circular=False)

Yields all class dependencies.

Omit circular and forward references by default.

Collect
  • base classes
  • attribute types
  • attribute choice types
  • recursively go through the inner classes
  • Ignore inner class references
  • Ignore native types.

Parameters:

Name Type Description Default
allow_circular bool

Allow circular references

False
Source code in xsdata/codegen/models.py
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
def dependencies(self, allow_circular: bool = False) -> Iterator[str]:
    """Yields all class dependencies.

    Omit circular and forward references by default.

    Collect:
        * base classes
        * attribute types
        * attribute choice types
        * recursively go through the inner classes
        * Ignore inner class references
        * Ignore native types.

    Args:
        allow_circular: Allow circular references
    """
    types = {ext.type for ext in self.extensions}

    for attr in self.attrs:
        types.update(attr.types)
        types.update(tp for choice in attr.choices for tp in choice.types)

    for tp in types:
        if tp.is_dependency(allow_circular):
            yield tp.qname

    for inner in self.inner:
        yield from inner.dependencies(allow_circular)

has_forward_ref()

Return whether this class has any forward references.

Source code in xsdata/codegen/models.py
685
686
687
688
689
690
691
692
693
694
def has_forward_ref(self) -> bool:
    """Return whether this class has any forward references."""
    for attr in self.attrs:
        if attr.is_forward_ref:
            return True

        if any(choice for choice in attr.choices if choice.is_forward_ref):
            return True

    return any(inner.has_forward_ref() for inner in self.inner)

Import dataclass

Python import statement model representation.

Parameters:

Name Type Description Default
qname str

The qualified name of the imported class

required
source str

The absolute module path

required
alias Optional[str]

Specifies an alias to avoid naming conflicts

field(default=None)
Source code in xsdata/codegen/models.py
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
@dataclass
class Import:
    """Python import statement model representation.

    Args:
        qname: The qualified name of the imported class
        source: The absolute module path
        alias: Specifies an alias to avoid naming conflicts
    """

    qname: str
    source: str
    alias: Optional[str] = field(default=None)

    @property
    def name(self) -> str:
        """Return the name of the imported class."""
        return namespaces.local_name(self.qname)

    @property
    def slug(self) -> str:
        """Return a slugified version of the imported class name."""
        return text.alnum(self.name)

name: str property

Return the name of the imported class.

slug: str property

Return a slugified version of the imported class name.