dapper91 / pydantic-xml

python xml for humans
https://pydantic-xml.readthedocs.io
The Unlicense
158 stars 16 forks source link

How to handle xsi:type ? #210

Open gizmo84 opened 1 month ago

gizmo84 commented 1 month ago

Hello and thanks again for this amazing tool / lib :)

I have a question regarding one of my parser:

<ns1:Description xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns1:CreationDescriptionType"> <ns1:Description xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns1:ContentEntityType">

How to best handle those xsi:type ? I tried different approach, but I'm not sure if I am on the right way.

Should I declare two class "CreationDescription" / "ContentEntity" or Generics ?

dapper91 commented 2 weeks ago

@gizmo84 Hi,

Could you provide more context please?

gizmo84 commented 2 weeks ago

One of my XML Schema is using xsi:type definition:

<ns1:Description xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns1:CreationDescriptionType">
<ns1:Description xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns1:ContentEntityType">

I was wondering how to best parse such content. I ended doing something like this, but I was not sure if it is the right way to implement it:

class Description(BaseXmlModel, tag="Description", nsmap={"xsi": "http://www.w3.org/2001/XMLSchema-instance"}):
    description: MediaInformation | CreationInformation | MultimediaContent = element()

class MediaDescription(Description):
    type: str = attr(name="type", ns="xsi", default="mpeg7:MediaDescriptionType")

class CreationDescription(Description):
    type: str = attr(name="type", ns="xsi", default="mpeg7:CreationDescriptionType")
dapper91 commented 1 week ago

@gizmo84 Hi,

I am not sure if I understood your problem correctly, but if I did I think your model should be like this:

class Description(BaseXmlModel, tag="Description", nsmap={"xsi": "http://www.w3.org/2001/XMLSchema-instance"}):
    pass

class MediaDescription(Description):
    type: Literal['mpeg7:MediaDescriptionType'] = attr(ns='xsi')
    description: MediaInformation = element()

class CreationDescription(Description):
    type: Literal['mpeg7:CreationDescriptionType'] = attr(ns='xsi')
    description: CreationInformation = element()