7

I'm trying to create a realtime report using an API that allows me to grab the data I need and returns it in XML format. What I want to know is, after receiving the response, how can I save it to an .xml file locally? Or cache it, that way I can parse it before parsing the response.

import requests
r = requests.get('url',  auth=('user', 'pass'))

I'm using requests since it's the easiest way to make a GET call in my opinion. Also, this is my first question and I'm barely starting to learn Python, I'd appreciate it if you guys had a little patience. Thanks.

I was looking at a similar question but for JSON, not sure if it would work the same, https://stackoverflow.com/a/17519020/4821590

import requests
import json
solditems = requests.get('https://github.com/timeline.json') # (your url)
data = solditems.json()
with open('data.json', 'w') as f:
    json.dump(data, f)
Community
  • 1
  • 1
Julio Montes
  • 71
  • 1
  • 1
  • 6

2 Answers2

22

If you want to be able to parse the returned XML before doing stuff with it, the xml tree is your friend.

import requests
import xml.etree.ElementTree as ET

r = requests.get('url',  auth=('user', 'pass'))
tree = ET.parse(r.text)
root = tree.getroot()

Otherwise, as jordanm has commented, you could just save it to a file and be done with it.

with open('data.xml', 'w') as f:
    f.write(r.text)
enigma
  • 3,476
  • 2
  • 17
  • 30
  • 1
    Thanks, I'm looking at the documentation now, really helpful. Sorry, don't have the reputation to upvote you. – Julio Montes Apr 22 '15 at 23:22
  • 1
    @JulioMontes if the answer is sufficient, you may mark it as accepted by clicking the tick next to the voting buttons. If you need extra help or hints, comment below and I'll help you out. Or you can wait it out a bit to see what other answers come up :) – enigma Apr 22 '15 at 23:24
  • 1
    Well, I'm going to keep this open (not sure if thats allowed) and do some digging myself and see how much further I get, don't want it all handed to me, I appreciate it though. – Julio Montes Apr 22 '15 at 23:31
  • 1
    I was wondering if there is a way for me to get the response and be able to choose what to print. I know when its `tree = ET.parse(r.text)` the response is the whole XML. However, I want to be selective. I tried just using `tree = ET.parse(r)` but I must be missing something. – Julio Montes May 01 '15 at 18:21
  • 1
    @juliomontes do you have an example? Do you mean like a particular child tag for instance? – enigma May 01 '15 at 20:37
  • 1
    yes, i'm trying to show only the values of the tags and not the whole xml file. ` Project X Site Management Stacey ` This is an example of the XML response that I get. I'm not sure how to print it, I've been trying: `for Asset in root: print child.tag, child.attrib` but doesn't work. – Julio Montes May 03 '15 at 15:46
  • 1
    Sorry, the above looks like a mess, but mainly I think it's that I'm trying to call all the child values in root. For example, Name, Scope.Name, and Owners.Name, etc. Not sure if it makes any sense. – Julio Montes May 03 '15 at 15:50
  • Are you able to figure out the solution to print only selected child? I am in need of that – Ravi Chandra Durvasula Nov 28 '17 at 14:59
13

Few notes related to Python3 (at least 3.6 versions):

1) when using xml.etree.ElementTree with requests, you use fromstring not parse. r.text returns a string, and xml.etree.ElementTree.parse is for files

import requests
import xml.etree.ElementTree as ET

r = requests.get("https://xml.returning.uri")
root = ET.fromstring(r.text)

2) This creates an element object as the root (no more tree). So to write it back out, you'll need to make it a tree:

tree = ET.ElementTree(root)
tree.write("file.xml")

From the docs

xml.etree.ElementTree.parse(source, parser=None) Parses an XML section into an element tree. source is a filename or file object containing XML data.

xml.etree.ElementTree.fromstring(text) Parses an XML section from a string constant. Same as XML(). text is a string containing XML data. Returns an Element instance

j5awry
  • 131
  • 1
  • 5