Homogeneous collections#
Homogeneous collection is a collection of same type elements.
The most common homogeneous collections are typing.List
, typing.Set
and
variable-length tuple typing.Tuple
(like Tuple[int, ...]
)
Primitive homogeneous collection#
A field of a primitive homogeneous collection type marked as pydantic_xml.element()
is bound
to the sub-elements texts.
class Company(BaseXmlModel):
products: List[str] = element(tag='Product')
<Company>
<Product>Several launch vehicles</Product>
<Product>Starlink</Product>
<Product>Starship</Product>
</Company>
{
"products": [
"Several launch vehicles",
"Starlink",
"Starship"
]
}
Model homogeneous collection#
A field of a model homogeneous collection type is bound to sub-elements. Then the sub-element is used
as the root for that sub-model. For more information see model data binding.
The tag
parameter is used to declare sub-elements tag to which the sub-models are bound.
If it is omitted the sub-model tag
parameter is used.
If it is omitted too field name is used (respecting pydantic
field aliases).
class Social(BaseXmlModel):
type: str = attr()
url: str
class Product(BaseXmlModel):
status: Literal['running', 'development'] = attr()
launched: Optional[int] = attr(default=None)
title: str
class Company(BaseXmlModel):
socials: Tuple[Social, ...] = element(tag='social')
products: List[Product] = element(tag='product')
<Company>
<social type="linkedin">https://www.linkedin.com/company/spacex</social>
<social type="twitter">https://twitter.com/spacex</social>
<social type="youtube">https://www.youtube.com/spacex</social>
<product status="running" launched="2013">Several launch vehicles</product>
<product status="running" launched="2019">Starlink</product>
<product status="development">Starship</product>
</Company>
{
"socials": [
{
"type": "linkedin",
"url": "https://www.linkedin.com/company/spacex"
},
{
"type": "twitter",
"url": "https://twitter.com/spacex"
},
{
"type": "youtube",
"url": "https://www.youtube.com/spacex"
}
],
"products": [
{
"status": "running",
"launched": 2013,
"title": "Several launch vehicles"
},
{
"status": "running",
"launched": 2019,
"title": "Starlink"
},
{
"status": "development",
"title": "Starship"
}
]
}
Dict homogeneous collection#
A field of a mapping homogeneous collection type is bound to sub-elements attributes:
class Company(BaseXmlModel):
products: List[Dict[str, str]] = element(tag='product')
<Company>
<product status="running" launched="2013"/>
<product status="running" launched="2019"/>
<product status="development"/>
</Company>
{
"products": [
{
"status": "running",
"launched": "2013"
},
{
"status": "running",
"launched": "2019"
},
{
"status": "development"
}
]
}
Adjacent sub-elements#
Some xml documents contain a list of adjacent elements related to each other. To group such elements a homogeneous collection of heterogeneous ones may be used:
class Products(RootXmlModel):
root: List[Tuple[str, Optional[int]]] = element(tag='info')
<Products>
<info type="status">running</info>
<info type="launched">2013</info>
<info type="status">running</info>
<info type="launched">2019</info>
<info type="status">development</info>
<info type="launched"></info>
</Products>
[
[
"running",
2013
],
[
"running",
2019
],
[
"development",
null
]
]
To group sub-elements with different tags it is necessary to declare a sub-model for each one:
class Product(BaseXmlModel, tag='product'):
status: str = attr()
title: str
class Launch(RootXmlModel[int], tag='launched'):
pass
class Products(RootXmlModel):
root: List[Tuple[Product, Optional[Launch]]]
<Products>
<product status="running">Several launch vehicles</product>
<launched>2013</launched>
<product status="running">Starlink</product>
<launched>2019</launched>
<product status="development">Starship</product>
</Products>
[
[
{
"title": "Several launch vehicles",
"status": "running"
},
2013
],
[
{
"title": "Starlink",
"status": "running"
},
2019
],
[
{
"title": "Starship",
"status": "development"
},
null
]
]