xsData: Python XML Binding
xsData is a complete data binding library for Python (current version 26.2) that allows developers to access and use XML and JSON documents as simple objects rather than using DOM. It features a code generator for XML schemas, DTD, WSDL definitions, XML & JSON documents, producing simple dataclasses with type hints. It is actively maintained with frequent releases, typically monthly or bi-monthly.
Warnings
- breaking Support for Python 3.9 was dropped in version 26.1. Users on Python 3.9 must upgrade their Python interpreter to >=3.10 to use newer xsData versions.
- gotcha Complex XML schemas can lead to circular import issues in the generated Python models, especially with the default `filenames` structure style. Consider using alternative structure styles like `namespaces`, `clusters`, or `single-package` to mitigate this.
- gotcha The parser's default behavior for type conversion is lenient, converting problematic values to `str` and emitting a `ConverterWarning` rather than raising an exception. This can mask data quality issues.
- breaking Recent versions (e.g., v26.2) have fixed issues where elements in the same choice but different branches were incorrectly merged as lists. This correction might alter the structure of generated dataclasses or the parsing behavior for existing XML documents if previous versions relied on the 'incorrect' merging logic.
- deprecated The `--ns-struct` CLI option has been deprecated. Its functionality is now provided by `--structure-style namespaces`.
Install
-
pip install xsdata -
pip install xsdata[cli,lxml,soap]
Imports
- XmlParser
from xsdata.formats.dataclass.parsers import XmlParser
- XmlSerializer
from xsdata.formats.dataclass.serializers import XmlSerializer
- generated_model_classes
from {your_package_name} import {ClassName}
Quickstart
from dataclasses import dataclass, field
from datetime import date
from xsdata.formats.dataclass.parsers import XmlParser
from xsdata.formats.dataclass.serializers import XmlSerializer
from xsdata.formats.dataclass.serializers.config import SerializerConfig
@dataclass
class Person:
first_name: str = field(metadata=dict(name='FirstName'))
last_name: str = field(metadata=dict(name='LastName'))
birth_date: date = field(metadata=dict(name='BirthDate', type='Attribute', format='%Y-%m-%d'))
@dataclass
class Family:
person: list[Person] = field(default_factory=list, metadata=dict(name='Person'))
# Create an instance
family_obj = Family(person=[
Person(first_name='John', last_name='Doe', birth_date=date(1980, 5, 15)),
Person(first_name='Jane', last_name='Doe', birth_date=date(1982, 11, 22))
])
# Serialize to XML
config = SerializerConfig(pretty_print=True, xml_declaration=True, encoding='UTF-8')
serializer = XmlSerializer(config=config)
xml_output = serializer.render(family_obj)
print(xml_output)
# Deserialize from XML
xml_input = """
<?xml version="1.0" encoding="UTF-8"?>
<Family>
<Person BirthDate="1980-05-15">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Person>
<Person BirthDate="1982-11-22">
<FirstName>Jane</FirstName>
<LastName>Doe</LastName>
</Person>
</Family>
"""
parser = XmlParser()
deserialized_family = parser.from_string(xml_input, Family)
print(deserialized_family.person[0].first_name)