Skip to content

Instantly share code, notes, and snippets.

@josuebrunel
Last active December 18, 2017 13:20
Show Gist options
  • Save josuebrunel/ca2f8357b7ddfff6586af851be4e04d5 to your computer and use it in GitHub Desktop.
Save josuebrunel/ca2f8357b7ddfff6586af851be4e04d5 to your computer and use it in GitHub Desktop.
from dateutil.parser import parse as dateutil_parse
from lxml import etree, objectify as xobject
def is_clean(element):
if not element.getchildren() and element.text is None:
return False
return all(is_clean(child) for child in element.iterchildren())
class BaseType(object):
"""Base data binding object
"""
tagname = None
namespace = None
nsmap = None
def __repr__(self):
return '<%s>' % self.tagname
@classmethod
def make_element(cls, tagname, value=None, namespace=None, nsmap=None):
M = xobject.ElementMaker(annotate=False, namespace=namespace,
nsmap=nsmap)
return M(tagname, value)
@property
def xml(self):
if isinstance(self, (ListType, DateType)):
return self.make_element(self.tagname, self.value, namespace=self.namespace)
tag = self.make_element(self.tagname, namespace=self.namespace, nsmap=self.nsmap)
for subelt in self.sequence:
attr = getattr(self, subelt, None)
if not attr:
continue
if isinstance(attr, (str, unicode)):
tag.append(self.make_element(subelt, attr, namespace=self.namespace))
else:
xml = attr.xml
if not is_clean(xml):
continue
tag.append(xml)
xobject.deannotate(tag, xsi_nil=True)
return tag
def __str__(self):
return etree.tostring(self.xml, pretty_print=True)
class ListType(BaseType):
"""Data binding class for ListType
"""
allowed_values = None
def __init__(self, value):
if value not in self.allowed_values:
raise ValueError('<%s> value (%s) not in %s' % (self.tagname, value,
self.allowed_values))
self.value = value
class DateType(BaseType):
def __init__(self, value):
self.value = dateutil_parse(value).date().isoformat()
class ComplexType(BaseType):
"""Data binding class for ComplexType
"""
sequence = None
# Couple example of Python objects
class Sex(ListType):
tagname = 'Sexe'
allowed_values = ('M', 'F')
class Credentials(ComplexType):
tagname = 'credentials'
sequence = ('login', 'password')
def __init__(self, data):
self.login = data['login']
self.password = data['password']
class Profile(ComplexType):
tagname = 'online'
sequence = ('url', 'credentials')
def __init__(self, data):
self.url = data['url']
self.credentials = Credentials(data)
class Identity(ComplexType):
tagname = 'Identite'
sequence = ('firstname', 'lastname', 'birthdate')
def __init__(self, data):
self.firstname = data['firstname']
self.lastname = data['lastname']
self.birthdate = data['birthdate']
class Address(ComplexType):
tagname = 'Adresse'
sequence = ('street', 'city', 'county', 'state', 'zipcode')
def __init__(self, data):
self.street = data['address_street']
self.city = data['address_city']
self.county = data['address_county']
self.state = data['address_state']
self.zipcode = data['address_zipcode']
class Person(ComplexType):
tagname = 'Personne'
sequence = ('identity', 'sex', 'address', 'profile')
def __init__(self, data):
self.identity = Identity(data)
self.sex = Sex(data['sex'])
self.address = Address(data)
self.profile = Profile(data)
# Data
DATA = {
'firstname': 'Josh',
'lastname': 'Loking',
'sex': 'M',
'birthdate': '2000-11-11',
'address_street': 'Main Street G. Washington',
'address_city': 'Ravenhill',
'address_county': 'Orange',
'address_state': 'Tennesse',
'address_zipcode': '99999',
'url': 'https://twitter.com/t0k3n',
'login': 't0k3n@example.com',
'password': 'Hakarimashita'
}
if __name__ == '__main__':
person = Person(DATA)
print(person)
@josuebrunel
Copy link
Author

Here is the result

josue%debian:~/workspace/reddit$
<Personne xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Identite>
    <firstname>Josh</firstname>
    <lastname>Loking</lastname>
    <birthdate>2000-11-11</birthdate>
  </Identite>
  <Sexe>M</Sexe>
  <Adresse>
    <street>Main Street G. Washington</street>
    <city>Ravenhill</city>
    <county>Orange</county>
    <state>Tennesse</state>
    <zipcode>99999</zipcode>
  </Adresse>
</Personne>

@josuebrunel
Copy link
Author

josue%debian:~/workspace/reddit/pyobj2xml$python pyobject2xml.py 
<Personne xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Identite>
    <firstname>Josh</firstname>
    <lastname>Loking</lastname>
    <birthdate>2000-11-11</birthdate>
  </Identite>
  <Sexe>M</Sexe>
  <Adresse>
    <street>Main Street G. Washington</street>
    <city>Ravenhill</city>
    <county>Orange</county>
    <state>Tennesse</state>
    <zipcode>99999</zipcode>
  </Adresse>
  <online>
    <url>https://twitter.com/t0k3n</url>
    <credentials>
      <login>t0k3n@example.com</login>
      <password>Hakarimashita</password>
    </credentials>
  </online>
</Personne>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment