Skip to content

Basics

Context

All binding metadata is generated and cached in a XmlContext instance. It's recommended to either reuse the same parser/serializer instance or reuse the context instance.

>>> from xsdata.formats.dataclass.context import XmlContext
>>> from xsdata.formats.dataclass.parsers import XmlParser
>>> from xsdata.formats.dataclass.parsers import JsonParser
>>> from xsdata.formats.dataclass.serializers import XmlSerializer
>>> from xsdata.formats.dataclass.serializers import JsonSerializer

>>> context = XmlContext()
>>> xml_parser = XmlParser(context=context)
>>> json_parser = JsonParser(context=context)
>>> xml_serializer = XmlSerializer(context=context)
>>> json_serializer = JsonSerializer(context=context)

Global Property Names

Through the XmlContext instance you can provide callables to apply a naming scheme for all models and their fields. This way you can avoid declaring them for every model, but you have to use the same context whenever you want to use a parser/serializer.

>>> from dataclasses import dataclass, field
>>> from datetime import date
>>> from xsdata.utils import text
>>> from xsdata.formats.dataclass.context import XmlContext
...
>>> @dataclass
... class Person:
...
...     first_name: str
...     last_name: str
...     birth_date: date = field(
...         metadata=dict(
...             type="Attribute",
...             format="%Y-%m-%d"
...         )
...     )
...
>>> obj = Person(
...     first_name="Chris",
...     last_name="T",
...     birth_date=date(1986, 9, 25),
... )
...
>>> context = XmlContext(
...     element_name_generator=text.camel_case,
...     attribute_name_generator=text.kebab_case
... )
>>> serializer = XmlSerializer(context=context)
>>> serializer.config.indent = "  "
>>> print(serializer.render(obj))
<?xml version="1.0" encoding="UTF-8"?>
<person birth-date="1986-09-25">
  <firstName>Chris</firstName>
  <lastName>T</lastName>
</person>

Parser Config

API: ParserConfig

base_url

Specifies a base URL when parsing from memory and the parser has to import included documents. e.g. XML Inclusions

Type: Optional[str]

Default: None

process_xinclude

Enable XML Inclusions processing. The parser will follow and retrieve the remote documents.

Type: bool

Default: False

load_dtd

Enable loading external dtd with LxmlEventHandler.

Type: bool

Default: False

class_factory

Override default object instantiation, to apply pre/post-initialization logic.

>>> from dataclasses import dataclass
>>> from xsdata.formats.dataclass.parsers import JsonParser
>>> from xsdata.formats.dataclass.parsers.config import ParserConfig
...
>>> def custom_class_factory(clazz, params):
...     if clazz.__name__ == "Person":
...         return clazz(**{k: v.upper() for k, v in params.items()})
...
...     return clazz(**params)
...

>>> config = ParserConfig(class_factory=custom_class_factory)
>>> parser = JsonParser(config=config)
...
>>> @dataclass
... class Person:
...     first_name: str
...     last_name: str
...
>>> json_str = """{"first_name": "chris", "last_name": "foo"}"""
...
...
>>> print(parser.from_string(json_str, Person))
Person(first_name='CHRIS', last_name='FOO')

Type: Callable[[Type[T], Dict[str, Any]], T]

Default: lambda: cls, params: return cls(**params)

fail_on_unknown_properties

Fail if the document includes properties not defined in the model.

Type: bool

Default: True

fail_on_unknown_attributes

Fail if the document includes attributes not defined in the model.

Type: bool

Default: False

fail_on_converter_warnings

Fail if a document value can't be correctly converted to python.

Type: bool

Default: False

Serializer Config

API: SerializerConfig

encoding

The text encoding for the XML header.

<?xml version="1.0" encoding="UTF-8"?>

Type: str

Default: "UTF-8"

xml_version

The XML version number to render (1.0|1.1).

<?xml version="1.0" encoding="UTF-8"?>

Type: str

Default: "1.0"

xml_declaration

Renders the XML declaration header.

Type: bool

Default: True

indent

Indent output by the given string.

Type: Optional[str]

Default: None

ignore_default_attributes

Ignore optional attributes with default values.

Type: bool

Default: False

schema_location

Render a xsi:schemaLocation attribute on the root element.

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xsdtesting elemS002.xsd"

Type: Optional[str]

Default: None

no_namespace_schema_location

Render a xsi:noNamespaceSchemaLocation attribute on the root element.

<doc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="groupB003.xsd">

Type: Optional[str]

Default: None

globalns

Dictionary containing global variables to extend or overwrite for typing.

When managing a big collection of models, it is sometimes tricky to split them into multiple python modules. Even more so if they depend on each other. For the models to be serializable by xsdata, they need to be able to import all other referenced models, which might not be possible due to circular imports.

One solution to get around this problem is to fence the imports within the python modules by using typing.TYPE_CHECKING and use this option to manually define the types.

from dataclasses import dataclass, field
from typing import TYPE_CHECKING, List

if TYPE_CHECKING:
    from tests.fixtures.typemapping.street import Street


@dataclass
class City:
    class Meta:
        global_type = False

    name: str
    streets: List["Street"] = field(default_factory=list)
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, List, Optional

if TYPE_CHECKING:
    from tests.fixtures.typemapping.city import City
    from tests.fixtures.typemapping.house import House


@dataclass
class Street:
    class Meta:
        global_type = False

    name: str
    city: Optional["City"] = None
    houses: List["House"] = field(default_factory=list)
from dataclasses import dataclass
from typing import TYPE_CHECKING, Optional

if TYPE_CHECKING:
    from tests.fixtures.typemapping.street import Street


@dataclass
class House:
    class Meta:
        global_type = False

    number: int
    street: Optional["Street"] = None
>>> from xsdata.formats.dataclass.serializers import XmlSerializer
>>> from xsdata.formats.dataclass.serializers.config import SerializerConfig
>>> from tests.fixtures.typemapping.city import City
>>> from tests.fixtures.typemapping.house import House
>>> from tests.fixtures.typemapping.street import Street
>>>
>>> city1 = City(name="footown")
>>> street1 = Street(name="foostreet")
>>> house1 = House(number=23)
>>> city1.streets.append(street1)
>>> street1.houses.append(house1)
>>> type_map = {"City": City, "Street": Street, "House": House}
>>> serializer_config = SerializerConfig(indent="  ", globalns=type_map)
>>> xml_serializer = XmlSerializer(config=serializer_config)
>>> serialized_house = xml_serializer.render(city1)
>>> print(serialized_house)
<?xml version="1.0" encoding="UTF-8"?>
<City>
  <name>footown</name>
  <streets>
    <name>foostreet</name>
    <houses>
      <number>23</number>
    </houses>
  </streets>
</City>

Type: Optional[Dict[str, Callable]] None