Skip to content

Instantly share code, notes, and snippets.

@e-roux
Created February 5, 2020 07:02
Show Gist options
  • Save e-roux/1ccc1689e7f3926ad3a9c1778749791f to your computer and use it in GitHub Desktop.
Save e-roux/1ccc1689e7f3926ad3a9c1778749791f to your computer and use it in GitHub Desktop.
Pydantic
from xml.etree.ElementTree import Element
import xml.etree.ElementTree as ET
from collections.abc import Iterator
from pydantic import BaseModel
from typing import Optional
def get_children(fragment, eltname):
return filter(lambda elt: elt.tag != eltname, fragment.find(eltname))
def is_subschema(cls, prop):
return '$ref' in cls.schema()['properties'][prop]
class XMLSchema(BaseModel):
@classmethod
def parse_raw(cls, data: Element, _type=None):
#print(_type)
if isinstance(data, Iterator):
data = list(data)
if len(data) > 1:
print("Y-a un hic")
data = data[0]
try:
_type = data.find('type').text
except AttributeError:
pass
#print(data, cls.__annotations__.values())
#print([(k, is_subschema(cls, k)) for k, v in cls.__annotations__.items()])
print(data)
res = {k: cls._get_node_val(data, k, subcls, _type) for k, subcls in cls.__annotations__.items()}
return cls(**res)
@classmethod
def _get_node_val(cls, data, k, subcls, _type):
try:
res = subcls.parse_raw(get_children(data, k), _type) if is_subschema(cls, k) else data.find(k).text
except AttributeError as e:
# print(data, k, subcls, e)
res = data.text
return res
class Sub(XMLSchema):
name: Optional[str]
ja: Optional[str]
aja: Optional[str]
class UserSchema(XMLSchema):
type: str
name: int
slug: str=None
sub: Sub
xml = ET.fromstring('''<root><type>type1</type><name>1</name><slug>azea aeza</slug><sub><name>blabla</name></sub></root>''')
UserSchema.parse_raw(xml).json()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment