Raw fields#

Raw element typed fields#

The library supports raw xml elements. It is helpful when the element schema is unknown or its schema is too complex to define a model describing it.

To declare a raw element field annotate it with xml.etree.ElementTree.Element (or lxml.etree._Element for lxml).

Since pydantic doesn’t support arbitrary types by default it is necessary to allow them by setting arbitrary_types_allowed flag. See documentation for more details.

Model
class Contact(BaseXmlModel, tag='contact'):
    url: HttpUrl


class Contacts(
    BaseXmlModel,
    tag='contacts',
    arbitrary_types_allowed=True,
):
    contacts_raw: List[Element] = element(tag='contact', exclude=True)

    @computed_element
    def parse_raw_contacts(self) -> List[Contact]:
        contacts: List[Contact] = []
        for contact_raw in self.contacts_raw:
            if url := contact_raw.attrib.get('url'):
                contact = Contact(url=url)
            elif (link := contact_raw.find('link')) is not None:
                contact = Contact(url=link.text)
            else:
                contact = Contact(url=contact_raw.text.strip())

            contacts.append(contact)

        return contacts
Document
<contacts>
    <contact url="https://www.linkedin.com/company/spacex" />
    <contact>
        <link>https://twitter.com/spacex</link>
    </contact>
    <contact>https://www.youtube.com/spacex</contact>
</contacts>
<contacts>
    <contact>https://www.linkedin.com/company/spacex</contact>
    <contact>https://twitter.com/spacex</contact>
    <contact>https://www.youtube.com/spacex</contact>
</contacts>