{"id":4187,"library":"pydantic-xml","title":"Pydantic XML Extension","description":"Pydantic-xml is a Pydantic extension that provides XML binding for model fields, enabling seamless XML serialization and deserialization. It is deeply integrated with Pydantic, supporting most of its features. The library is actively maintained, with frequent releases addressing bug fixes and new features, often several times a month.","status":"active","version":"2.19.0","language":"en","source_language":"en","source_url":"https://github.com/dapper91/pydantic-xml","tags":["pydantic","xml","serialization","deserialization","lxml","data-validation"],"install":[{"cmd":"pip install pydantic-xml","lang":"bash","label":"Basic Installation"},{"cmd":"pip install pydantic-xml[lxml]","lang":"bash","label":"With lxml backend (recommended for performance)"}],"dependencies":[{"reason":"Core dependency for model definition and validation.","package":"pydantic","optional":false},{"reason":"Optional dependency for faster XML parsing and serialization, otherwise defaults to xml.etree.ElementTree.","package":"lxml","optional":true}],"imports":[{"symbol":"BaseXmlModel","correct":"from pydantic_xml import BaseXmlModel"},{"note":"Required for custom root types and models that directly represent the XML root element.","symbol":"RootXmlModel","correct":"from pydantic_xml import RootXmlModel"},{"note":"Top-level import is preferred for convenience and stability.","wrong":"from pydantic_xml.elements import attr","symbol":"attr","correct":"from pydantic_xml import attr"},{"note":"Top-level import is preferred for convenience and stability.","wrong":"from pydantic_xml.elements import element","symbol":"element","correct":"from pydantic_xml import element"},{"note":"Top-level import is preferred for convenience and stability. Used for deep element hierarchies without intermediate models.","wrong":"from pydantic_xml.elements import wrapped","symbol":"wrapped","correct":"from pydantic_xml import wrapped"}],"quickstart":{"code":"from typing import List, Optional\nfrom pydantic import HttpUrl\nfrom pydantic_xml import BaseXmlModel, attr, element\n\nclass Product(BaseXmlModel):\n    status: str = attr() # e.g., 'running', 'development'\n    launched: Optional[int] = attr(default=None)\n    title: str # Extracted from the element text\n\nclass Company(BaseXmlModel, tag='Company'):\n    trade_name: str = attr(name='trade-name')\n    website: HttpUrl = element()\n    products: List[Product] = element(tag='product', default_factory=list)\n\nxml_doc = \"\"\"\n<Company trade-name=\"SpaceX\">\n    <website>https://www.spacex.com</website>\n    <product status=\"running\" launched=\"2013\">Several launch vehicles</product>\n    <product status=\"running\" launched=\"2019\">Starlink</product>\n    <product status=\"development\">Starship</product>\n</Company>\n\"\"\"\n\n# Deserialize XML to a Pydantic model\ncompany = Company.from_xml(xml_doc)\nprint(f\"Company: {company.trade_name}, Website: {company.website}\")\nfor product in company.products:\n    print(f\"  Product: {product.title}, Status: {product.status}, Launched: {product.launched}\")\n\n# Serialize Pydantic model back to XML\nnew_xml_doc = company.to_xml(pretty_print=True)\nprint(\"\\nSerialized XML:\")\nprint(new_xml_doc.decode())\n","lang":"python","description":"This example demonstrates how to define XML serializable/deserializable models using `BaseXmlModel`, bind fields to XML attributes (`attr`), elements (`element`), and handle lists of sub-models. It covers both deserialization from an XML string and serialization back to XML."},"warnings":[{"fix":"Upgrade Pydantic to V2, migrate your Pydantic models, and ensure all models used with `pydantic-xml` are Pydantic V2 compatible. Avoid mixing `pydantic.v1.BaseModel` and `pydantic.BaseModel` in model hierarchies. Use `bump-pydantic` tool for initial migration of Pydantic models.","message":"Migration to Pydantic V2 (from Pydantic V1) requires significant changes. `pydantic-xml` 2.x supports Pydantic V2+. While `pydantic-xml` itself aims for compatibility, direct Pydantic V1 (`pydantic.v1.BaseModel`) and Pydantic V2 (`pydantic.BaseModel`) models cannot be mixed directly within the same hierarchy.","severity":"breaking","affected_versions":"Pydantic < 2.0 to Pydantic >= 2.0.0"},{"fix":"Ensure all namespace aliases used in `ns` or `nsmap` parameters are correctly defined in the model's `__xml_nsmap__` class attribute.","message":"Since v2.16.0, an exception is now raised if a namespace alias used in a model or field is not found within the model's namespace map (`__xml_nsmap__`). This changed behavior from silently ignoring missing aliases.","severity":"breaking","affected_versions":">=2.16.0"},{"fix":"Change base class from `BaseXmlModel` to `RootXmlModel` for models representing the root of an XML document and defining a `root` field for the content.","message":"The way custom root types are declared changed significantly around `pydantic-xml` 2.0.0. Custom root models must now inherit from `RootXmlModel` instead of `BaseXmlModel` with `__root__` attribute.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Always explicitly specify `tag='your-xml-tag'` for elements or `name='your-xml-attribute'` for attributes, and `tag='YourRootTag'` for `BaseXmlModel` if the XML names don't exactly match Python field/class names or casing.","message":"By default, `pydantic-xml` maps Python field names directly to XML element/attribute names. If the XML tag or attribute name differs (e.g., due to different casing or hyphens), `ParsingError` will be raised unless `tag` or `name` arguments are explicitly provided to `element()`, `attr()`, or `BaseXmlModel`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Prefer using `typing.Annotated` with Pydantic's functional validators/serializers (`field_serializer`, `field_validator`, `AfterValidator`, etc.) for defining custom serialization/validation logic.","message":"The syntax for defining custom field serializers and validators has evolved with Pydantic V2. While older `@xml_field_serializer` and `@xml_field_validator` decorators are still functional, the `Annotated` pattern with `pydantic.field_serializer` and `pydantic.field_validator` (or `pydantic.BeforeValidator`, `pydantic.AfterValidator`, etc.) is the recommended Pydantic V2 approach for better integration and type safety.","severity":"gotcha","affected_versions":">=2.17.0 (for new syntax support)"},{"fix":"Update any downstream consumers of XML generated by `pydantic-xml` to expect the new `bool` and `None` encoding formats. If the old format is strictly required, implement custom serializers for these types.","message":"The encoding format for `bool` and `None` types changed. `bool` values now serialize as lowercase `'true'` or `'false'` instead of title-case `'True'` or `'False'`. `None` values now serialize as an empty string `''` instead of `'None'`.","severity":"breaking","affected_versions":">=2.9.0"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}