Skip to content

schema

xsdata.codegen.parsers.schema

SchemaParser dataclass

Bases: UserXmlParser

Xml schema definition parser.

Apply implied rules, set indexes, resolve location paths...

Parameters:

Name Type Description Default
location Optional[str]

The schema location uri

None
target_namespace Optional[str]

The schema target namespace

None

Attributes:

Name Type Description
index int

The current element index

indices List[int]

The child element indices

element_form Optional[str]

The schema element form

attribute_form Optional[str]

The schema attribute form

default_attributes Optional[str]

The schema default attributes

default_open_content Optional[DefaultOpenContent]

The schema default open content

Source code in xsdata/codegen/parsers/schema.py
 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
 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
400
401
402
403
404
405
406
407
408
409
410
411
412
@dataclass
class SchemaParser(UserXmlParser):
    """Xml schema definition parser.

    Apply implied rules, set indexes, resolve
    location paths...

    Args:
        location: The schema location uri
        target_namespace: The schema target namespace

    Attributes:
        index: The current element index
        indices: The child element indices
        element_form: The schema element form
        attribute_form: The schema attribute form
        default_attributes: The schema default attributes
        default_open_content: The schema default open content
    """

    location: Optional[str] = field(default=None)
    target_namespace: Optional[str] = field(default=None)
    index: int = field(default_factory=int, init=False)
    indices: List[int] = field(default_factory=list, init=False)
    element_form: Optional[str] = field(default=None, init=False)
    attribute_form: Optional[str] = field(default=None, init=False)
    default_attributes: Optional[str] = field(default=None, init=False)
    default_open_content: Optional[xsd.DefaultOpenContent] = field(
        default=None, init=False
    )

    def start(
        self,
        clazz: Optional[Type[T]],
        queue: List[XmlNode],
        objects: List[Parsed],
        qname: str,
        attrs: Dict,
        ns_map: Dict,
    ):
        """Build and queue the XmlNode for the starting element.

        Override to set the current element index and append it in
        child element indices.

        Args:
            clazz: The target class type, auto locate if omitted
            queue: The XmlNode queue list
            objects: The list of all intermediate parsed objects
            qname: The element qualified name
            attrs: The element attributes
            ns_map: The element namespace prefix-URI map
        """
        self.index += 1
        self.indices.append(self.index)
        super().start(clazz, queue, objects, qname, attrs, ns_map)

    def end(
        self,
        queue: List[XmlNode],
        objects: List[Parsed],
        qname: str,
        text: Optional[str],
        tail: Optional[str],
    ) -> Any:
        """Parse the last xml node and bind any intermediate objects.

        Override to set the xsd model index and ns map.

        Args:
            queue: The XmlNode queue list
            objects: The list of all intermediate parsed objects
            qname: The element qualified name
            text: The element text content
            tail: The element tail content

        Returns:
            Whether the binding process was successful.
        """
        item = queue[-1]
        super().end(queue, objects, qname, text, tail)

        obj = objects[-1][1]
        self.set_index(obj, self.indices.pop())
        self.set_namespace_map(obj, getattr(item, "ns_map", None))

        return obj

    def start_schema(self, attrs: Dict[str, str]):
        """Start schema element entrypoint.

        Store the element/attribute default forms and the
        default attributes, for later processing.

        Args:
            attrs: The element attributes

        """
        self.element_form = attrs.get("elementFormDefault")
        self.attribute_form = attrs.get("attributeFormDefault")
        self.default_attributes = attrs.get("defaultAttributes")

    def end_schema(self, obj: T):
        """End schema element entrypoint.

        Normalize various properties for the schema and it's children.

        Args:
            obj: The xsd schema instance.
        """
        if isinstance(obj, xsd.Schema):
            self.set_schema_forms(obj)
            self.set_schema_namespaces(obj)
            self.add_default_imports(obj)
            self.resolve_schemas_locations(obj)

    def end_attribute(self, obj: T):
        """End attribute element entrypoint.

        Assign the schema's default form in the attribute instance,
        if it doesn't define its own.

        Args:
            obj: The xsd attribute instance

        """
        if isinstance(obj, xsd.Attribute) and obj.form is None and self.attribute_form:
            obj.form = FormType(self.attribute_form)

    def end_complex_type(self, obj: T):
        """End complex type element entrypoint.

        Post parsing processor to apply default open content and attributes if
        applicable.

        Default open content doesn't apply if the current complex type
        has one of complex content, simple content or has its own open
        content.

        Args:
            obj: The xsd complex type instance
        """
        if not isinstance(obj, xsd.ComplexType):
            return

        if obj.default_attributes_apply and self.default_attributes:
            attribute_group = xsd.AttributeGroup(ref=self.default_attributes)
            obj.attribute_groups.insert(0, attribute_group)

        if (
            obj.simple_content
            or obj.complex_content
            or obj.open_content
            or not self.default_open_content
        ):
            return

        if self.default_open_content.applies_to_empty or self.has_elements(obj):
            obj.open_content = self.default_open_content

    def end_default_open_content(self, obj: T):
        """End default open content element entrypoint.

        If the open content element mode is suffix, adjust
        the index to trick later processors into putting attrs
        derived from this open content last in the generated classes.

        Store the obj for later processing.

        Args:
            obj: The xsd default open content instance
        .
        """
        if isinstance(obj, xsd.DefaultOpenContent):
            if obj.any and obj.mode == Mode.SUFFIX:
                obj.any.index = sys.maxsize

            self.default_open_content = obj

    def end_element(self, obj: T):
        """End element entrypoint.

        Assign the schema's default form in the element instance,
        if it doesn't define its own.

        Args:
            obj: The xsd element instance
        """
        if isinstance(obj, xsd.Element) and obj.form is None and self.element_form:
            obj.form = FormType(self.element_form)

    def end_extension(self, obj: T):
        """End extension element entrypoint.

        Assign the schema's default open content in the extension instance,
        if it doesn't define its own.

        Args:
            obj: The xsd extension instance
        """
        if isinstance(obj, xsd.Extension) and not obj.open_content:
            obj.open_content = self.default_open_content

    @classmethod
    def end_open_content(cls, obj: T):
        """End open content element entrypoint.

        If the open content element mode is suffix, adjust
        the index to trick later processors into putting attrs
        derived from this open content last in the generated classes.

        Args:
            obj: The xsd open content instance

        """
        if isinstance(obj, xsd.OpenContent) and obj.any and obj.mode == Mode.SUFFIX:
            obj.any.index = sys.maxsize

    def end_restriction(self, obj: T):
        """End restriction element entrypoint.

        Assign the schema's default open content in the restriction instance,
        if it doesn't define its own.

        Args:
            obj: The xsd restriction instance
        """
        if isinstance(obj, xsd.Restriction) and not obj.open_content:
            obj.open_content = self.default_open_content

    def set_schema_forms(self, obj: xsd.Schema):
        """Cascade schema forms to elements and attributes.

        Args:
            obj: The xsd schema instance
        """
        if self.element_form:
            obj.element_form_default = FormType(self.element_form)
        if self.attribute_form:
            obj.attribute_form_default = FormType(self.attribute_form)

        for child_element in obj.elements:
            child_element.form = FormType.QUALIFIED

        for child_attribute in obj.attributes:
            child_attribute.form = FormType.QUALIFIED

    def set_schema_namespaces(self, obj: xsd.Schema):
        """Set the schema target namespace.

        If the schema was imported and doesn't have a target namespace,
        it automatically inherits the parent schema target namespace.

        Args:
            obj: The xsd schema instance
        """
        obj.target_namespace = obj.target_namespace or self.target_namespace

    def resolve_schemas_locations(self, obj: xsd.Schema):
        """Resolve the location attributes of the schema.

        This method covers relative paths and implied schema
        locations to common namespaces like xsi, xlink.

        Schema elements with location attribute:
            - override
            - redefines
            - include
            - import

        Args:
            obj: The xsd schema instance
        """
        if not self.location:
            return

        obj.location = self.location
        for over in obj.overrides:
            over.location = self.resolve_path(over.schema_location)

        for red in obj.redefines:
            red.location = self.resolve_path(red.schema_location)

        for inc in obj.includes:
            inc.location = self.resolve_path(inc.schema_location)

        for imp in obj.imports:
            imp.location = self.resolve_local_path(imp.schema_location, imp.namespace)

    def resolve_path(self, location: Optional[str]) -> Optional[str]:
        """Resolve the given location string.

        Use the parser location attribute as the base uri.

        Args:
            location: The location uri

        Returns:
            The resolved location or None if it was not resolved
        """
        return urljoin(self.location, location) if self.location and location else None

    def resolve_local_path(
        self,
        location: Optional[str],
        namespace: Optional[str],
    ) -> Optional[str]:
        """Resolve the given namespace to one of the local standard schemas.

        w3.org protects against fetching common schemas not from a browser,
        instead we use the local xsdata copies.

        Args:
            location: The schema location
            namespace: The schema namespace

        Returns:
            The local path or the absolute remote uri.
        """
        common_ns = Namespace.get_enum(namespace)
        local_path = common_ns.location if common_ns else None

        if local_path and (not location or location.find("w3.org/") > 0):
            return local_path

        return self.resolve_path(location)

    @classmethod
    def has_elements(cls, obj: ElementBase) -> bool:
        """Helper function to check if instance has children.

        Valid children: xs:element, xs:any, xs:group.

        Args:
            obj: The element base instance

        Returns:
            The bool result.

        """
        accepted_types = (xsd.Element, xsd.Any, xsd.Group)
        return any(
            isinstance(child, accepted_types) or cls.has_elements(child)
            for child in obj.children()
        )

    @classmethod
    def set_namespace_map(cls, obj: Any, ns_map: Optional[Dict]):
        """Add common namespaces like xml, xsi, xlink if they are missing.

        These prefixes are implied and we need to support them.

        Args:
            obj: A xsd model instance
            ns_map: The namespace prefix-URI map
        """
        if hasattr(obj, "ns_map"):
            if ns_map:
                obj.ns_map.update(
                    {prefix: uri for prefix, uri in ns_map.items() if uri}
                )

            ns_list = obj.ns_map.values()
            obj.ns_map.update(
                {
                    ns.prefix: ns.uri
                    for ns in Namespace.common()
                    if ns.uri not in ns_list
                }
            )

    @classmethod
    def set_index(cls, obj: Any, index: int):
        """Helper method to set an object's index.

        Args:
            obj: A xsd model instance
            index: The index number
        """
        if hasattr(obj, "index"):
            obj.index = index

    @classmethod
    def add_default_imports(cls, obj: xsd.Schema):
        """Add missing imports to the standard schemas.

        We might need to generate the classes from these
        common schemas, so add these implied imports.

        Args:
            obj: The xsd schema instance
        """
        imp_namespaces = [imp.namespace for imp in obj.imports]
        xsi_ns = Namespace.XSI.uri
        if xsi_ns in obj.ns_map.values() and xsi_ns not in imp_namespaces:
            obj.imports.insert(0, xsd.Import(namespace=xsi_ns))

start(clazz, queue, objects, qname, attrs, ns_map)

Build and queue the XmlNode for the starting element.

Override to set the current element index and append it in child element indices.

Parameters:

Name Type Description Default
clazz Optional[Type[T]]

The target class type, auto locate if omitted

required
queue List[XmlNode]

The XmlNode queue list

required
objects List[Parsed]

The list of all intermediate parsed objects

required
qname str

The element qualified name

required
attrs Dict

The element attributes

required
ns_map Dict

The element namespace prefix-URI map

required
Source code in xsdata/codegen/parsers/schema.py
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
def start(
    self,
    clazz: Optional[Type[T]],
    queue: List[XmlNode],
    objects: List[Parsed],
    qname: str,
    attrs: Dict,
    ns_map: Dict,
):
    """Build and queue the XmlNode for the starting element.

    Override to set the current element index and append it in
    child element indices.

    Args:
        clazz: The target class type, auto locate if omitted
        queue: The XmlNode queue list
        objects: The list of all intermediate parsed objects
        qname: The element qualified name
        attrs: The element attributes
        ns_map: The element namespace prefix-URI map
    """
    self.index += 1
    self.indices.append(self.index)
    super().start(clazz, queue, objects, qname, attrs, ns_map)

end(queue, objects, qname, text, tail)

Parse the last xml node and bind any intermediate objects.

Override to set the xsd model index and ns map.

Parameters:

Name Type Description Default
queue List[XmlNode]

The XmlNode queue list

required
objects List[Parsed]

The list of all intermediate parsed objects

required
qname str

The element qualified name

required
text Optional[str]

The element text content

required
tail Optional[str]

The element tail content

required

Returns:

Type Description
Any

Whether the binding process was successful.

Source code in xsdata/codegen/parsers/schema.py
 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
def end(
    self,
    queue: List[XmlNode],
    objects: List[Parsed],
    qname: str,
    text: Optional[str],
    tail: Optional[str],
) -> Any:
    """Parse the last xml node and bind any intermediate objects.

    Override to set the xsd model index and ns map.

    Args:
        queue: The XmlNode queue list
        objects: The list of all intermediate parsed objects
        qname: The element qualified name
        text: The element text content
        tail: The element tail content

    Returns:
        Whether the binding process was successful.
    """
    item = queue[-1]
    super().end(queue, objects, qname, text, tail)

    obj = objects[-1][1]
    self.set_index(obj, self.indices.pop())
    self.set_namespace_map(obj, getattr(item, "ns_map", None))

    return obj

start_schema(attrs)

Start schema element entrypoint.

Store the element/attribute default forms and the default attributes, for later processing.

Parameters:

Name Type Description Default
attrs Dict[str, str]

The element attributes

required
Source code in xsdata/codegen/parsers/schema.py
105
106
107
108
109
110
111
112
113
114
115
116
117
def start_schema(self, attrs: Dict[str, str]):
    """Start schema element entrypoint.

    Store the element/attribute default forms and the
    default attributes, for later processing.

    Args:
        attrs: The element attributes

    """
    self.element_form = attrs.get("elementFormDefault")
    self.attribute_form = attrs.get("attributeFormDefault")
    self.default_attributes = attrs.get("defaultAttributes")

end_schema(obj)

End schema element entrypoint.

Normalize various properties for the schema and it's children.

Parameters:

Name Type Description Default
obj T

The xsd schema instance.

required
Source code in xsdata/codegen/parsers/schema.py
119
120
121
122
123
124
125
126
127
128
129
130
131
def end_schema(self, obj: T):
    """End schema element entrypoint.

    Normalize various properties for the schema and it's children.

    Args:
        obj: The xsd schema instance.
    """
    if isinstance(obj, xsd.Schema):
        self.set_schema_forms(obj)
        self.set_schema_namespaces(obj)
        self.add_default_imports(obj)
        self.resolve_schemas_locations(obj)

end_attribute(obj)

End attribute element entrypoint.

Assign the schema's default form in the attribute instance, if it doesn't define its own.

Parameters:

Name Type Description Default
obj T

The xsd attribute instance

required
Source code in xsdata/codegen/parsers/schema.py
133
134
135
136
137
138
139
140
141
142
143
144
def end_attribute(self, obj: T):
    """End attribute element entrypoint.

    Assign the schema's default form in the attribute instance,
    if it doesn't define its own.

    Args:
        obj: The xsd attribute instance

    """
    if isinstance(obj, xsd.Attribute) and obj.form is None and self.attribute_form:
        obj.form = FormType(self.attribute_form)

end_complex_type(obj)

End complex type element entrypoint.

Post parsing processor to apply default open content and attributes if applicable.

Default open content doesn't apply if the current complex type has one of complex content, simple content or has its own open content.

Parameters:

Name Type Description Default
obj T

The xsd complex type instance

required
Source code in xsdata/codegen/parsers/schema.py
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
def end_complex_type(self, obj: T):
    """End complex type element entrypoint.

    Post parsing processor to apply default open content and attributes if
    applicable.

    Default open content doesn't apply if the current complex type
    has one of complex content, simple content or has its own open
    content.

    Args:
        obj: The xsd complex type instance
    """
    if not isinstance(obj, xsd.ComplexType):
        return

    if obj.default_attributes_apply and self.default_attributes:
        attribute_group = xsd.AttributeGroup(ref=self.default_attributes)
        obj.attribute_groups.insert(0, attribute_group)

    if (
        obj.simple_content
        or obj.complex_content
        or obj.open_content
        or not self.default_open_content
    ):
        return

    if self.default_open_content.applies_to_empty or self.has_elements(obj):
        obj.open_content = self.default_open_content

end_default_open_content(obj)

End default open content element entrypoint.

If the open content element mode is suffix, adjust the index to trick later processors into putting attrs derived from this open content last in the generated classes.

Store the obj for later processing.

Parameters:

Name Type Description Default
obj T

The xsd default open content instance

required

.

Source code in xsdata/codegen/parsers/schema.py
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def end_default_open_content(self, obj: T):
    """End default open content element entrypoint.

    If the open content element mode is suffix, adjust
    the index to trick later processors into putting attrs
    derived from this open content last in the generated classes.

    Store the obj for later processing.

    Args:
        obj: The xsd default open content instance
    .
    """
    if isinstance(obj, xsd.DefaultOpenContent):
        if obj.any and obj.mode == Mode.SUFFIX:
            obj.any.index = sys.maxsize

        self.default_open_content = obj

end_element(obj)

End element entrypoint.

Assign the schema's default form in the element instance, if it doesn't define its own.

Parameters:

Name Type Description Default
obj T

The xsd element instance

required
Source code in xsdata/codegen/parsers/schema.py
196
197
198
199
200
201
202
203
204
205
206
def end_element(self, obj: T):
    """End element entrypoint.

    Assign the schema's default form in the element instance,
    if it doesn't define its own.

    Args:
        obj: The xsd element instance
    """
    if isinstance(obj, xsd.Element) and obj.form is None and self.element_form:
        obj.form = FormType(self.element_form)

end_extension(obj)

End extension element entrypoint.

Assign the schema's default open content in the extension instance, if it doesn't define its own.

Parameters:

Name Type Description Default
obj T

The xsd extension instance

required
Source code in xsdata/codegen/parsers/schema.py
208
209
210
211
212
213
214
215
216
217
218
def end_extension(self, obj: T):
    """End extension element entrypoint.

    Assign the schema's default open content in the extension instance,
    if it doesn't define its own.

    Args:
        obj: The xsd extension instance
    """
    if isinstance(obj, xsd.Extension) and not obj.open_content:
        obj.open_content = self.default_open_content

end_open_content(obj) classmethod

End open content element entrypoint.

If the open content element mode is suffix, adjust the index to trick later processors into putting attrs derived from this open content last in the generated classes.

Parameters:

Name Type Description Default
obj T

The xsd open content instance

required
Source code in xsdata/codegen/parsers/schema.py
220
221
222
223
224
225
226
227
228
229
230
231
232
233
@classmethod
def end_open_content(cls, obj: T):
    """End open content element entrypoint.

    If the open content element mode is suffix, adjust
    the index to trick later processors into putting attrs
    derived from this open content last in the generated classes.

    Args:
        obj: The xsd open content instance

    """
    if isinstance(obj, xsd.OpenContent) and obj.any and obj.mode == Mode.SUFFIX:
        obj.any.index = sys.maxsize

end_restriction(obj)

End restriction element entrypoint.

Assign the schema's default open content in the restriction instance, if it doesn't define its own.

Parameters:

Name Type Description Default
obj T

The xsd restriction instance

required
Source code in xsdata/codegen/parsers/schema.py
235
236
237
238
239
240
241
242
243
244
245
def end_restriction(self, obj: T):
    """End restriction element entrypoint.

    Assign the schema's default open content in the restriction instance,
    if it doesn't define its own.

    Args:
        obj: The xsd restriction instance
    """
    if isinstance(obj, xsd.Restriction) and not obj.open_content:
        obj.open_content = self.default_open_content

set_schema_forms(obj)

Cascade schema forms to elements and attributes.

Parameters:

Name Type Description Default
obj Schema

The xsd schema instance

required
Source code in xsdata/codegen/parsers/schema.py
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
def set_schema_forms(self, obj: xsd.Schema):
    """Cascade schema forms to elements and attributes.

    Args:
        obj: The xsd schema instance
    """
    if self.element_form:
        obj.element_form_default = FormType(self.element_form)
    if self.attribute_form:
        obj.attribute_form_default = FormType(self.attribute_form)

    for child_element in obj.elements:
        child_element.form = FormType.QUALIFIED

    for child_attribute in obj.attributes:
        child_attribute.form = FormType.QUALIFIED

set_schema_namespaces(obj)

Set the schema target namespace.

If the schema was imported and doesn't have a target namespace, it automatically inherits the parent schema target namespace.

Parameters:

Name Type Description Default
obj Schema

The xsd schema instance

required
Source code in xsdata/codegen/parsers/schema.py
264
265
266
267
268
269
270
271
272
273
def set_schema_namespaces(self, obj: xsd.Schema):
    """Set the schema target namespace.

    If the schema was imported and doesn't have a target namespace,
    it automatically inherits the parent schema target namespace.

    Args:
        obj: The xsd schema instance
    """
    obj.target_namespace = obj.target_namespace or self.target_namespace

resolve_schemas_locations(obj)

Resolve the location attributes of the schema.

This method covers relative paths and implied schema locations to common namespaces like xsi, xlink.

Schema elements with location attribute
  • override
  • redefines
  • include
  • import

Parameters:

Name Type Description Default
obj Schema

The xsd schema instance

required
Source code in xsdata/codegen/parsers/schema.py
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
def resolve_schemas_locations(self, obj: xsd.Schema):
    """Resolve the location attributes of the schema.

    This method covers relative paths and implied schema
    locations to common namespaces like xsi, xlink.

    Schema elements with location attribute:
        - override
        - redefines
        - include
        - import

    Args:
        obj: The xsd schema instance
    """
    if not self.location:
        return

    obj.location = self.location
    for over in obj.overrides:
        over.location = self.resolve_path(over.schema_location)

    for red in obj.redefines:
        red.location = self.resolve_path(red.schema_location)

    for inc in obj.includes:
        inc.location = self.resolve_path(inc.schema_location)

    for imp in obj.imports:
        imp.location = self.resolve_local_path(imp.schema_location, imp.namespace)

resolve_path(location)

Resolve the given location string.

Use the parser location attribute as the base uri.

Parameters:

Name Type Description Default
location Optional[str]

The location uri

required

Returns:

Type Description
Optional[str]

The resolved location or None if it was not resolved

Source code in xsdata/codegen/parsers/schema.py
306
307
308
309
310
311
312
313
314
315
316
317
def resolve_path(self, location: Optional[str]) -> Optional[str]:
    """Resolve the given location string.

    Use the parser location attribute as the base uri.

    Args:
        location: The location uri

    Returns:
        The resolved location or None if it was not resolved
    """
    return urljoin(self.location, location) if self.location and location else None

resolve_local_path(location, namespace)

Resolve the given namespace to one of the local standard schemas.

w3.org protects against fetching common schemas not from a browser, instead we use the local xsdata copies.

Parameters:

Name Type Description Default
location Optional[str]

The schema location

required
namespace Optional[str]

The schema namespace

required

Returns:

Type Description
Optional[str]

The local path or the absolute remote uri.

Source code in xsdata/codegen/parsers/schema.py
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
def resolve_local_path(
    self,
    location: Optional[str],
    namespace: Optional[str],
) -> Optional[str]:
    """Resolve the given namespace to one of the local standard schemas.

    w3.org protects against fetching common schemas not from a browser,
    instead we use the local xsdata copies.

    Args:
        location: The schema location
        namespace: The schema namespace

    Returns:
        The local path or the absolute remote uri.
    """
    common_ns = Namespace.get_enum(namespace)
    local_path = common_ns.location if common_ns else None

    if local_path and (not location or location.find("w3.org/") > 0):
        return local_path

    return self.resolve_path(location)

has_elements(obj) classmethod

Helper function to check if instance has children.

Valid children: xs:element, xs:any, xs:group.

Parameters:

Name Type Description Default
obj ElementBase

The element base instance

required

Returns:

Type Description
bool

The bool result.

Source code in xsdata/codegen/parsers/schema.py
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
@classmethod
def has_elements(cls, obj: ElementBase) -> bool:
    """Helper function to check if instance has children.

    Valid children: xs:element, xs:any, xs:group.

    Args:
        obj: The element base instance

    Returns:
        The bool result.

    """
    accepted_types = (xsd.Element, xsd.Any, xsd.Group)
    return any(
        isinstance(child, accepted_types) or cls.has_elements(child)
        for child in obj.children()
    )

set_namespace_map(obj, ns_map) classmethod

Add common namespaces like xml, xsi, xlink if they are missing.

These prefixes are implied and we need to support them.

Parameters:

Name Type Description Default
obj Any

A xsd model instance

required
ns_map Optional[Dict]

The namespace prefix-URI map

required
Source code in xsdata/codegen/parsers/schema.py
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
@classmethod
def set_namespace_map(cls, obj: Any, ns_map: Optional[Dict]):
    """Add common namespaces like xml, xsi, xlink if they are missing.

    These prefixes are implied and we need to support them.

    Args:
        obj: A xsd model instance
        ns_map: The namespace prefix-URI map
    """
    if hasattr(obj, "ns_map"):
        if ns_map:
            obj.ns_map.update(
                {prefix: uri for prefix, uri in ns_map.items() if uri}
            )

        ns_list = obj.ns_map.values()
        obj.ns_map.update(
            {
                ns.prefix: ns.uri
                for ns in Namespace.common()
                if ns.uri not in ns_list
            }
        )

set_index(obj, index) classmethod

Helper method to set an object's index.

Parameters:

Name Type Description Default
obj Any

A xsd model instance

required
index int

The index number

required
Source code in xsdata/codegen/parsers/schema.py
388
389
390
391
392
393
394
395
396
397
@classmethod
def set_index(cls, obj: Any, index: int):
    """Helper method to set an object's index.

    Args:
        obj: A xsd model instance
        index: The index number
    """
    if hasattr(obj, "index"):
        obj.index = index

add_default_imports(obj) classmethod

Add missing imports to the standard schemas.

We might need to generate the classes from these common schemas, so add these implied imports.

Parameters:

Name Type Description Default
obj Schema

The xsd schema instance

required
Source code in xsdata/codegen/parsers/schema.py
399
400
401
402
403
404
405
406
407
408
409
410
411
412
@classmethod
def add_default_imports(cls, obj: xsd.Schema):
    """Add missing imports to the standard schemas.

    We might need to generate the classes from these
    common schemas, so add these implied imports.

    Args:
        obj: The xsd schema instance
    """
    imp_namespaces = [imp.namespace for imp in obj.imports]
    xsi_ns = Namespace.XSI.uri
    if xsi_ns in obj.ns_map.values() and xsi_ns not in imp_namespaces:
        obj.imports.insert(0, xsd.Import(namespace=xsi_ns))