How to remove select characters from xml parse in python / django?
Question: **Context**

I am working on a django project and I need to loop through a nested
dictionary to print the values

Here's the dictionary:

> {body{u'@copyright': u'All data copyright Unitrans ASUCD/City of Davis
> 2015.', u'predictions': {u'@routeTitle': u'A',
> u'@dirTitleBecauseNoPredictions': u'Outbound to El Cemonte',
> u'@agencyTitle': u'Unitrans ASUCD/City of Davis', u'@stopTag': u'22258',
> u'@stopTitle': u'Silo Terminal & Haring Hall (WB)', u'@routeTag': u'A',
> u'message': [{u'@text': u'Weekend service is running Monday-Wednesday Dec.
> 28-30.', u'@priority': u'Normal'}, {u'@text': u'The A-line and Z-line do not
> run on weekends. Use O-line for weekend service.', u'@priority':
> u'Normal'}]}}}

I am parsing the dictionary from the following url:
[http://webservices.nextbus.com/service/publicXMLFeed?command=predictions&a=unitrans&r=A&s=22258](http://webservices.nextbus.com/service/publicXMLFeed?command=predictions&a=unitrans&r=A&s=22258)

**Problem 1**

I am getting trouble displaying the values of keys with '@' in them using
django template tags, for example

    
    
        {% for i in data%}
          {% i.@copyright %}
        {% endfor %}
    

This gives an error saying could not parse remainder.

**Problem 2**

One of the values has a nested dictionary in it with square brackets

> [{u'@text': u'Weekend service is running Monday-Wednesday Dec. 28-30.',
> u'@priority': u'Normal'}, {u'@text': u'The A-line and Z-line do not run on
> weekends. Use O-line for weekend service.', u'@priority': u'Normal'}]

I cannot loop through this using for loop template tags

**The solution I have in mind**

In order to solve this and make it simpler I am looking to strip the
characters `'@'`, `'['` and `']'`from the xml, this would leave me with a much
simpler dictionary which would be easy to loop through.

**My Python Code Right Now in views.py**

    
    
    import xmltodict
    import requests
    def prediction(request, line, s_id):
        url = "http://webservices.nextbus.com/service/publicXMLFeed?  command=predictions&a=unitrans&r=" + line + "&s=" + s_id
        data = requests.get(url)
        data = xmltodict.parse(data, dict_constructor=dict)
        data_dict = {}
        data_dict["data"] = data
        return render(request, 'routes/predictions.html', data_dict)
    

**What I want to display on page predictions.html**

    
    
    Route Tag: A
    
    Message : Weekend Service is running Monday-Wednesday Dec. 28-30.
    The A-Line and Z-Line do not run on weekends. use O-Line for weekend service.
    
    Priority: Normal
    

I would appreciate any inputs on this problem. Thank you for your time.


Answer: In xmltodict, the '@' symbols are there to indicate attributes of xml nodes,
and the '[' and ']' are used to delimit element values that are themselves a
list of values. (Here, it indicates the 'message' value is itself a list of
two message objects). You can certainly try to read in the dict as raw text
and scrape out what you need, but that won't take advantage of the reason most
people are importing it to begin with: To organize the data and make it easier
to access.

Instead of scraping the text, you can easily craft a template that would just
pull the specific values from the dict that you want. Your data dict should be
structured something like this:

    
    
    {
        body:
        {
            u'@copyright': u'All data copyright Unitrans ASUCD/City of Davis 2015.',
            u'predictions':
            {
                u'@routeTitle': u'A',
                u'@dirTitleBecauseNoPredictions': u'Outbound to El Cemonte',
                u'@agencyTitle': u'Unitrans ASUCD/City of Davis',
                u'@stopTag': u'22258',
                u'@stopTitle': u'Silo Terminal & Haring Hall (WB)',
                u'@routeTag': u'A',
                u'message':
                [
                    {
                        u'@text': u'Weekend service is running Monday-Wednesday Dec. 28-30.',
                        u'@priority': u'Normal'
                    },
                    {
                        u'@text': u'The A-line and Z-line do not run on weekends. Use O-line for weekend service.',
                        u'@priority': u'Normal'
                    }
                ]
            }
        }
    }
    

To get the output you want, create a template tailored for this data and then
just insert directly the values you need. Something like this: (apologies, I
don't know django template syntax exactly)

    
    
    Route Tag: {{ data_dict.body.predictions.routeTitle }}
    
    Messages :
    <ul>
    {% for msg in data_dict.body.predictions.message %}
        <li>{{ msg.text }} (Priority: {{ msg.priority }})</li>
    {% endfor %}
    </ul>
    

