Python Forum
How to display XML tree structure with Python?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to display XML tree structure with Python?
#11
@mreshko, This is 3 year old request and I doubt OP will take requests to develop functionality for you. I would suggest that you try to modify the code provided here and amend it to suit your needs. If you face a problem you cannot solve - start a new thread, post your code in python tags, any traceback - in error tags and ask specific questions.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#12
Be aware that the user hasn't visited forum in two years, so unlikely that you will get a response.
But, you never know.
Reply
#13
For those who might be interested, I've added a few things to the code, so now it displays the siblings number, e.g. 1 in "3.1", the text value from the element, and the number of identical siblings.

xml_root = etree.fromstring(xml_file_content)
raw_tree = etree.ElementTree(xml_root)
nice_tree = collections.OrderedDict()
 
for tag in xml_root.iter():
    path = re.sub('\[[0-9]+\]', '', raw_tree.getpath(tag))
    
    if path not in nice_tree:
        nice_tree[path] = {'attribs':[], 'values': '', 'count': 1}
    else:
        nice_tree[path]['count'] += 1
        
    if len(tag.keys()) > 0:
        nice_tree[path]['attribs'].extend(attrib for attrib in tag.keys() if attrib not in nice_tree[path])  
        
    if tag.text:
        nice_tree[path]['values'] = ' '.join(tag.text.split())
        

last_level = -1
sibling = 0
for path, d in nice_tree.items():
    
    this_level = int(path.count('/') - 1)
    if this_level == last_level:
        sibling += 1
    else:
        sibling = 0
    last_level = this_level
    
    print('{0}{1}.{2}: {3} [{4}] [{5}] [{6}]'.format('    ' * this_level,
                                                     this_level,
                                                     sibling,
                                                     path.split('/')[-1],
                                                     ', '.join(d['attribs']) if len(d['attribs']) > 0 else '',
                                                     d['values'],
                                                     d['count']))                      

The code in my last post was incorrectly calculating siblings id. This is an update which should fix it.

xml_root = etree.fromstring(file_content)
raw_tree = etree.ElementTree(xml_root)
nice_tree = collections.OrderedDict()
 
for tag in xml_root.iter():
    path = re.sub('\[[0-9]+\]', '', raw_tree.getpath(tag))
    
    if path not in nice_tree:
        nice_tree[path] = {'attribs':[], 'values':'', 'count':1}
    else:
        nice_tree[path]['count'] += 1
        
    if len(tag.keys()) > 0:
        nice_tree[path]['attribs'].extend(attrib for attrib in tag.keys() if attrib not in nice_tree[path])  
        
    if tag.text:
        nice_tree[path]['values'] = ' '.join(tag.text.split())
        

last_level = -1
siblings = []
for path, d in nice_tree.items():
    
    this_level = int(path.count('/') - 1)
    
    if len(siblings)-1 < this_level:
        siblings.append(0)
    elif this_level == last_level:
        siblings[this_level] += 1
    elif this_level < last_level:
        siblings[last_level] = 0
        siblings[this_level] += 1
    else:
        siblings[this_level] = 0
        
    last_level = this_level
    
    print('{0}{1}.{2}: {3} [{4}] [{5}] [{6}]'.format('    ' * this_level,
                                                     this_level,
                                                     siblings[this_level],
                                                     path.split('/')[-1],
                                                     ', '.join(d['attribs']) if len(d['attribs']) > 0 else '',
                                                     d['values'],
                                                     d['count']))
Reply
#14
...not quite. Need to replace

siblings[last_level] = 0
with

siblings[this_level+1:] = [0] * (len(siblings) - this_level - 1)
That should now be it. Hopefully. Rolleyes
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Web app structure with python as backend alt19 1 1,926 Oct-06-2020, 11:28 PM
Last Post: scidam
  Cant set api response as tree in Element tree hey_arnold 4 3,635 Mar-04-2019, 03:25 PM
Last Post: dsarin

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020