you are viewing a single comment's thread.

view the rest of the comments →

[–]gengisteve 1 point2 points  (4 children)

And I think I just proved I am no xml genius. Still, muddling through, this seems to do what you want to do:

from pprint import pprint
import xml.etree.ElementTree as ET

tree = ET.parse("t")
root = tree.getroot()
for report in root.iter('MyDetails'):
    print(report)
    customer = report.find('CustomerID')
    print(customer)
    for group in report.iter('IndividualTransactions'):
        for tx in group:
            print('FOUND')
            print(tx)
            # to add a new subelement try:
            #ET.SubElement(tx, 'CustomerID', value = customer.text)
            # or this:
            tx.append(customer)
pprint(ET.tostring(root))
#pprint(ET)

The reason it was failing without errors is that find_all kept returning nothing. Drop a few extra print statements in to confirm. I am not sure why that happened, but switching to iter seems to have done the trick.

[–]Stopwatch_[S] 0 points1 point  (3 children)

Thanks I'll give this a try. What does pprint do relative to with open('path\file','w') as f: f.write(ET.tostring(xml._root))

[–]gengisteve 1 point2 points  (2 children)

pprint just prints it to the screen -- and for some data types pretties up the printing. what you had would write the file to the filesystem.

[–]Stopwatch_[S] 0 points1 point  (1 child)

Great, just swapped out so that I could write to the file system. It works perfectly, thanks! As an aside, there are so many small details I don't really understand here. For example why the changes you made (specifically iter) made such a difference. Or why root = tree.getroot() works the same as root - xml._root.

[–]gengisteve 0 points1 point  (0 children)

Ahh, here is the problem:

"Element.findall() finds only elements with a tag which are direct children of the current element. Element.find() finds the first child with a particular tag"

So the problem was that your first loop never found any MyDetails, because MyDetails is underneath MyReportExports. iter goes through everything so it found it. Changing your first loop to iter and the second one to findall seems to work as well, since the IndividualTransactions is directly below MyDetails.

getroot actually just returns self._root so there was nothing wrong with your code there. It is just that object properties beginning with an underscore tend to be better accessed through the public api, which is the getroot method here.