Model#
Root model#
A root model is bound to the root xml element with the tag matching the model tag
or class name.
If the corresponding element not found pydantic_xml.ParsingError
exception is raised.
Model
class Company(BaseXmlModel, tag='company'):
title: str
Document
<company>SpaceX</company>
{
"title": "SpaceX"
}
Sub-models#
See models.
Namespaces#
You can declare the root model namespace by setting parameters ns
and nsmap
.
where ns
is the element namespace alias and nsmap
is a namespace mapping.
The namespace mapping is inherited by all the model field:
Model
class Company(
BaseXmlModel,
tag='company',
ns='co',
nsmap={'co': 'http://www.company.com/co'},
):
founded: dt.date = element()
website: HttpUrl = element(tag='web-site', ns='co')
Document
<co:company xmlns:co="http://www.company.com/co">
<co:founded>2002-03-14</co:founded>
<co:web-site>https://www.spacex.com</co:web-site>
</co:company>
{
"founded": "2002-03-14",
"website": "https://www.spacex.com"
}
Custom root type#
Pydantic
supports so-called custom root type.
It works for primitive types:
Model
class WebSite(RootXmlModel):
root: str
class Company(BaseXmlModel, tag='company'):
website: WebSite
Document
<company>
<website>https://www.spacex.com</website>
</company>
{
"website": "https://www.spacex.com"
}
collection types:
Model
class Company(RootXmlModel, tag='company'):
root: Dict[str, str]
Document
<company trade-name="SpaceX" type="Private"/>
{
"trade-name": "SpaceX",
"type":"Private"
}
and model types:
Model
class Socials(RootXmlModel, tag='socials'):
root: List[HttpUrl] = element(tag='social')
class Contacts(RootXmlModel[Socials], tag='contacts'):
pass
Document
<contacts>
<socials>
<social>https://www.linkedin.com/company/spacex</social>
<social>https://twitter.com/spacex</social>
<social>https://www.youtube.com/spacex</social>
</socials>
</contacts>
[
"https://www.linkedin.com/company/spacex",
"https://twitter.com/spacex",
"https://www.youtube.com/spacex"
]
Self-referencing models#
pydantic
library supports self-referencing models.
Within the model, you can refer to a not-yet-constructed model using a string.
Model
class Directory(BaseXmlModel, tag="Directory"):
name: str = attr(name='Name')
dirs: Optional[List['Directory']] = element(tag='Directory', default=None)
Document
<Directory Name="root">
<Directory Name="etc">
<Directory Name="ssh"/>
<Directory Name="init"/>
</Directory>
<Directory Name="bin"/>
</Directory>
{
"name": "root",
"dirs": [
{
"name": "etc",
"dirs": [
{
"name": "ssh"
},
{
"name": "init"
}
]
},
{
"name": "bin"
}
]
}
That allows you to parse hierarchical data structures:
model.py:
import pathlib
from typing import List, Optional
from pydantic_xml import BaseXmlModel, attr, element
class File(BaseXmlModel, tag="File"):
name: str = attr(name='Name')
mode: str = attr(name='Mode')
class Directory(BaseXmlModel, tag="Directory"):
name: str = attr(name='Name')
mode: str = attr(name='Mode')
dirs: Optional[List['Directory']] = element(tag='Directory', default=None)
files: Optional[List[File]] = element(tag='File', default_factory=list)
xml_doc = pathlib.Path('./doc.xml').read_text()
directory = Directory.from_xml(xml_doc)
json_doc = pathlib.Path('./doc.json').read_text()
assert directory == Directory.model_validate_json(json_doc)
doc.xml:
<Directory Name="root" Mode="rwxr-xr-x">
<Directory Name="etc" Mode="rwxr-xr-x">
<Directory Name="ssh" Mode="rwxr-xr-x"/>
<File Name="passwd" Mode="-rw-r--r--"/>
<File Name="hosts" Mode="-rw-r--r--"/>
</Directory>
<Directory Name="bin" Mode="rwxr-xr-x"/>
<Directory Name="usr" Mode="rwxr-xr-x">
<Directory Name="bin" Mode="rwxr-xr-x"/>
</Directory>
</Directory>
doc.json:
{
"name": "root",
"mode": "rwxr-xr-x",
"dirs": [
{
"name": "etc",
"mode": "rwxr-xr-x",
"dirs": [
{
"name": "ssh",
"mode": "rwxr-xr-x"
}
],
"files": [
{
"name": "passwd",
"mode": "-rw-r--r--"
},
{
"name": "hosts",
"mode": "-rw-r--r--"
}
]
},
{
"name": "bin",
"mode": "rwxr-xr-x",
"dirs": null,
"files": []
},
{
"name": "usr",
"mode": "rwxr-xr-x",
"dirs": [
{
"name": "bin",
"mode": "rwxr-xr-x",
"dirs": null,
"files": []
}
],
"files": []
}
],
"files": []
}