Skip to content

Instantly share code, notes, and snippets.

@e-roux
Created February 3, 2020 21:19
Show Gist options
  • Save e-roux/dfeb77bcc7f9aa52fc2eddef2a8f32c3 to your computer and use it in GitHub Desktop.
Save e-roux/dfeb77bcc7f9aa52fc2eddef2a8f32c3 to your computer and use it in GitHub Desktop.
Sample pre_load and xml in marshmallow
from xml.etree.ElementTree import Element
import xml.etree.ElementTree as ET
from marshmallow import (Schema, pre_load)
from marshmallow.fields import (
Str,
Integer,
List,
Nested
)
from marshmallow.exceptions import ValidationError
class BaseSchema(Schema):
@staticmethod
def _extract_value(k, v, elt):
try:
if isinstance(v, Nested):
return v.schema.__class__().load(elt)
else:
return elt.text
except AttributeError as e:
print(f'key {k} unknown')
return ''
@pre_load
def _(self, data, many, **kwargs):
if isinstance(data, Element):
res = dict()
for k, v in self.declared_fields.items():
try:
if isinstance(v, Nested) and v.many:
res[k] = [self._extract_value(k, v, elt) for elt in data.findall(k)]
else:
elt = data.find(k)
res[k] = self._extract_value(k, v, elt)
except ValidationError as e:
print(f'key {k} unknown')
res[k] = {}
return res
return data
class A(BaseSchema):
name = Str()
slug = Str()
qsdq = Str()
class B(BaseSchema):
aze = Integer()
xcw = Nested(A(), many=True)
qsd = Nested(A(), many=True)
# df = Nested(A())
class root(BaseSchema):
B = Nested(B())
xml = ET.fromstring('''<root><B><aze>1</aze><qsd><name>NAME</name><slug>SLUG</slug></qsd>
<qsd><name>NAME1</name><slug>SLUG2</slug></qsd></B></root>''')
root().load(xml)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment