1. Jesper Noehr
  2. django-piston
  3. Issues
Issue #76 open

posting XML doesn´t work

created an issue

I´ve succesfully implemented piston to work with JSON, but I´m struggeling with XML (which is what I have to use). not sure if this is a bug or a documentation-issue or just me not being able to figure it out ...

here´s the most basic code I use for testing:



import urllib2 data = '<project><id>1</id></project>' url = "http://myurl/api/1/rendersettings/?format=xml" headers = {'Content-Type':'text/xml'} req = urllib2.Request(url, data, headers) response = urllib2.urlopen(req) }}}

I´ve been playing around with "data", adding "<response>" and "<?xml version="1.0" ?>" - but it´s still not working. maybe it´s just an issue of the docs not explaining the xml-format.

my handler (for testing) looks like this: {{{


@require_mime('xml') def create(self, request, project_id): ... if request.content_type: data = request.data raw_data = request.raw_post_data print "DATA:", data print "RAW DATA:", raw_data }}}

raw_data is correct, but data is not available.

sorry for crossposting, but the google-group seems to be dead.

Comments (12)

  1. Jesper Noehr repo owner
    • changed status to open

    Yes, there's no XML de-serializer. I never implemented one, since I didn't have a good way of converting an XML structure to a dictionary, uniformly.

    You can see it lacking here: http://bitbucket.org/jespern/django-piston/src/tip/piston/emitters.py#cl-376 (it simply returns None), so this is where you'd put it, should you decide to write one.

    If you do, I'll include in the official distribution.

    Sorry for not having written one, and for causing confusion.

  2. Anonymous

    It really REALLY REALLY should raise a Not Implemented error in this case. I just spent several hours trying to figure out what was wrong with the deserialization of my xml, only to eventually find this. Returning None is not an appropriate response, since all the docs suggest that XML is fully supported.

    Please fix this bug, and fix the docs.

  3. Tom Coote


    I have created a patch queue and added an XML Mimer. The mimer works very well, it converts XML to the same dictionary structure as you would expect from the JSON mimer.

    I decided in the end to create something from scratch using pythons xml support.

  4. Anonymous


    Your patch has GPL'd code which is viral - meaning that django-piston can't accept it without also dropping BSD and becoming GPL.

    So you could either re-license, or we'll need to wait for a different patch.


  5. Anonymous

    Hello everybody,

    I've experimented the same issue, so I decided to create my own XML de-serializer.

    I've never found on the web code that can transform xml format to dict python object and dict python object to xml format. So I've changed the line in django-piston/piston/emitters.py : Mimer.register(lambda *a: None, ('text/xml',)) By Mimer.register(myxml2dict.xml2dict, ('text/xml',))

    So you have to import one of my new file : import myxml2dict

    Here is the code of that file :

    from lxml import etree
    def iter(root, l):
        for element in root:
            my_dict = {}
            d = {}
            new_l = []
            if element.keys():
                for attr, value in element.items():
                    d[attr] = value
            my_dict[element.tag] = new_l
            children = list(element)
            # if subelement we recusrsivly iter on it
            if len(children) > 0:
                iter(element, new_l)
            # add dictionnary
    def xml2dict(str):
        root = etree.fromstring(str)
        dict = {}
        list = []
        # first iteration, check attributes in root node
        d = {}
        if root.keys():
            for attr, value in root.items():
                d[attr] = value
        dict[root.tag] = list
        iter(root, list)
        return dict

    So ok now you have the transformation of the xml in a dict format. That piece of code uses lxml, so be sure it's installed on your machine : http://lxml.de/

    Now when you want to get some datas :

    import mydict2xml
    class XMLHandler(BaseHandler):
           allowed_methods = ('POST',)
           def create(self, request):
                 data = request.data # with a request with curl for example
                 return mydict2xml.dict2xml(data)

    And here you go, you get your xml format where you can do business code on it.

    Here is the content of the mydict2xml.py file :

    from lxml import etree
    def iter(root, attributes):
        for key, value in attributes.iteritems():
            # root node
            child = etree.SubElement(root, key)
            if type(value) == list:
                # get dictionnary attributes            
                for ix,attributes in enumerate(value):
                    # if we have some attributes
                    if ix == 0 and len(attributes) > 0 :
                        for k, v in attributes.iteritems():                    
                            child.attrib[k] = v
                        iter(child, attributes)
    def dict2xml(dict):
        for key, value in dict.iteritems():
            # root node
            root = etree.Element(key)
            if type(value) == list:
                # get dictionnary attributes
                for ix,attributes in enumerate(value):
                    # if we have some attributes
                    if ix == 0 and len(attributes) > 0 :
                        for k, v in attributes.iteritems():                    
                            root.attrib[k] = v
                        iter(root, attributes)
        str = etree.tostring(dict2xml(dict))
        return str

    Here too, you need lxml module.

    These scripts haven't a license yet, but I want to make them free to everyone under a MIT or GPL or BSD license. So use them the way you want!

    I hope it will help you and will be integrated in the next release of piston. Piston helped me, so I want to thank you by bringing my little contribution.

    Thank you

  6. Anonymous

    By the way, my name is Guillaume Cisco, and you can contact me at : guillaumecisco [at] g m a i l [dooot] c o m

  7. Joshua Ginsberg
    • changed version to 0.2.3

    At the least, the 0.2.3 release will raise a not-implemented error. I'll try to spark some discussion on the list regarding what way people seem content with parsing the XML, as my personal uses have all been JSON and urlencoded submissions.

  8. Log in to comment