Append XML responses in Python - python

I am trying to parse multiple XML responses in one file. However, when I write a responses to file, it shows only last one. I assume I need to add append somewhere in order to keep all responses.
Here is my code:
import json
import xml.etree.ElementTree as ET
#loop test
feins = ['800228936', '451957238']
for i in feins:
rr = requests.get('https://pdb-services.nipr.com/pdb-xml-reports/hitlist_xml.cgi?report_type=0&id_fein={}'.format(i),auth=('test', 'test'))
root = ET.fromstring(rr.text)
tree = ET.ElementTree(root)
tree.write("file.xml")

Try changing
for i in feins:
...
tree = ET.ElementTree(root)
tree.write("file.xml")
to (note the indentation):
for i in feins:
...
tree = ET.ElementTree(root)
with open("file.xml", "wb") as f:
tree.write(f)
and see if it works.

Related

xml.etree.ElementTree how can i add attribute inside of a node?

I want the build an xml file and i made some research. I decided the use xml tree but i couldn't manage the use it like i want.
I want the generate this xml.
<Invoice test="how can i generate this ?">
</Invoice>
i am doing in python
import xml.etree.ElementTree as gfg
def GenerateXML(fileName):
root = gfg.Element("Invoice")
root.tail = 'test="how can i generate this ?"'
tree = gfg.ElementTree(root)
with open(fileName, "wb") as files:
tree.write(files)
It's generate xml file look like:
<Invoice />test="how can i generate this ?"
I know i shouln't use tail for i want. But i can't find a way for the make a xml look like what i want. Thank you for help.
This piece of XML structure is called "attribute".
You can get it using the set(attr, value) method.
import xml.etree.ElementTree as gfg
def GenerateXML(fileName):
root = gfg.Element("Invoice")
root.set('test', 'how can i generate this ?')
tree = gfg.ElementTree(root)
with open(fileName, "wb") as files:
tree.write(files)
GenerateXML('test.xml')
test.xml:
<Invoice test="how can i generate this ?" />

How to write Element Tree dump into file

I am try to write the xml dump into the another file. Here is my python code
import xml.etree.ElementTree as ET
tree = ET.parse('extract_orginal.xml')
root = tree.getroot()
with open('extract.xml', 'w') as extract:
for item in root.findall(f"doc[#id='289e1292134534']"):
extract.write(ET.dump(item))
Getting the output as "NONE" in the extract.xml file. Can you please help me.
From the docs of .dump():
"Write element tree or element structure to sys.stdout. This function should be used for debugging only."
The function .dump() returns None!
I think you want to use .tostring():
import xml.etree.ElementTree as ET
tree = ET.parse('extract_orginal.xml')
root = tree.getroot()
with open('extract.xml', 'w') as extract:
for item in root.findall(f"doc[#id='289e1292134534']"):
extract.write(ET.tostring(item, encoding="utf-8"))

no modifications in XML file after running python code

I wrote a code that must modify some values in a xml file. it looks to be working, but when i open this xml file threw PyCharm where i have added the modified file, it just doesn't change a thing. If anyone gave a respond to such a question, please point me where is it. Here is the code as well as the xml.
import xml.etree.ElementTree as ET
tree = ET.parse("farms.xml")
root = tree.getroot()
for elem in root.findall('farm'):
elem.set('money', '2000')
money = elem.get('money')
print(money)
xml
<farms>
<farm farmId="1" name="Моя ферма" color="1" loan="0.000000" money="213" loanAnnualInterestRate="304.166656">
<players>
</players>
</farm>
</farms>
What you are missing is writing the tree back to disk.
import xml.etree.ElementTree as ET
tree = ET.parse("farms.xml")
root = tree.getroot()
for elem in root.findall('farm'):
elem.set('money', '2000')
with open('new_farms.xml', 'wb') as f:
tree.write(f)
It works for me.
Additionally,
print(xml.etree.ElementTree.tostring(root))
will show what you expect.

Parsing an xml file and creating another from the parsed object

I am trying to parse an xml file(containing bad characters) using lxml module in recover = True mode.
Below is the code snippet
from lxml import etree
f=open('test.xml')
data=f.read()
f.close()
parser = etree.XMLParser(recover=True)
x = etree.fromstring(data, parser=parser)
Now I want to create another xml file (test1.xml) from the above object (x)
Could anyone please help in this matter.
Thanks
I think this is what you are searching for
from lxml import etree
# opening the source file
with open('test.xml','r') as f:
# reading the number
data=f.read()
parser = etree.XMLParser(recover=True)
# fromstring() parses XML from a string directly into an Element
x = etree.fromstring(data, parser=parser)
# taking the content retrieved
y = etree.tostring(x, pretty_print=True).decode("utf-8")
# writing the content on the output file
with open('test1.xml','w') as f:
f.write(y)

Append filename in Elementtree

I have an XML document called sync_list.xml structured like this:
root = ET.Element("root")
synced = ET.SubElement(root, "synced")
synced.set("name", "Already Synced")
sfile = ET.SubElement(synced, "sfile")
sfile.set("name", "Filename")
sfile.text = "base"
tree = ET.ElementTree(root)
tree.write("sync_list.xml")
so that I end up with:
<root><synced name="Already Synced"><sfile name="Filename">base</sfile></synced></root>
and I'm multiple files within a directory. I would like to "append" those file names as a new sfile entry each time a file is opened. So I would end up with something like this:
<root><synced name="Already Synced"><sfile name="Filename">base</sfile><sfile name="Filename">File1.blah</sfile><sfile name="Filename">File2.blah</sfile><sfile name="Filename">File3.blah</sfile></synced></root>
How would I achieve this? Thank you so much for your help.
You almost there. You just need to read the file back and find the <synced> element in it:
from __future__ import unicode_literals
from xml.etree import cElementTree as etree
tree = etree.parse('sync_list.xml')
synced = tree.find('synced')
for filename in ["file\u00b9", "file2", "file3"]:
sfile = etree.SubElement(synced, "sfile", name="Filename")
sfile.text = filename
tree.write('sync_list_appended.xml', encoding='utf-8', xml_declaration=True)

Categories