jpadilla / django-rest-framework-xml

XML support for Django REST Framework

Home Page:http://jpadilla.github.io/django-rest-framework-xml

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

XMLParser() item list

xavella opened this issue · comments

As described in:
http://stackoverflow.com/questions/35631886/django-rest-xmlparser-cannot-parse-item-list

It appears XMLParser() does not support item lists. When parsing an XML list, the parser returns the last list item only (as a dict()). This behaviour is unexpected, and from what i can tell, not documented.

Example code follows: 
XML = """<?xml version="1.0" encoding="UTF-8"?>
                <root>
                <item>
                    <ID>item_1</ID>
                    <Description>first item</Description>
                </item>
                <item>
                    <ID>item_2</ID>
                    <Description>second item</Description>
                </item>
                </root>
            """
from django.conf import settings    
settings.configure()
from django.utils.six import BytesIO
from rest_framework_xml.parsers import XMLParser

data_stream = BytesIO(XML)
parsed_data = XMLParser().parse(data_stream)

print parsed_data

Which returns:

{'item': {'ID': 'item_2', 'Description': 'second item'}}

Given XML lists are common, and the code does not throw a warning/error; I would consider this a bug.

I had this same problem. My solution was to subclass XMLParser, give it a list of tags to consider as "list elements", and then override _xml_convert:

class XMLParserAttributes(XMLParser):
    list_tags = [
        'Classification',
        'BulletPoint',
        'Job'
    ]

    # ...

    def _xml_convert(self, element):
        # ....
        if children[0].tag in self.list_tags:
            data = []
            for child in children:
                data.append(self._xml_convert(child))

Why not include a 'item_tag_name' class property like there is on the XMLRenderer to make it easier to subclass without having to reimplement _xml_convert method?