简体   繁体   中英

How to remove select characters from xml parse in python / django?

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

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.

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM