2

Is there an efficient way to get the level of each node in xml, using the python xml parser? The level of a node can also be determined by counting the closing tags while parsing the xml top-down, however, I need help in that too :). Thanks!

IssamLaradji
  • 6,637
  • 8
  • 43
  • 68

3 Answers3

5

maybe this could be an initial idea:

from xml.etree import ElementTree
from xml.etree.ElementTree import iterparse

level = 0

for (event, node) in iterparse( fileName, ['start', 'end', 'start-ns', 'end-ns'] ):

    if event == 'end':
        level -= 1

    if event == 'start':
        level += 1

    # do soething with node ...
ziwou
  • 66
  • 1
  • Thanks! thats exactly what I was looking for! :), other answers were great, but they intended to find the level of one node, not each node. – IssamLaradji Mar 01 '13 at 07:51
0

I'm assuming by "python xml parser" you mean xml.etree. There are other libraries as well (such as lxml) which can make this job easier, but according to this answer there's no easy way to access the parent elements using this library. However, the workaround presented there (creating a mapping of parents to the whole tree) is enough to determine the level of any given element:

import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()
# root = ET.fromstring(...)   # Alternative

parent_map = dict((c, p) for p in root.getiterator() for c in p)
def level(node):
    return level(parent_map[node])+1 if node in parent_map else 0
Community
  • 1
  • 1
mgibsonbr
  • 21,755
  • 7
  • 70
  • 112
0

I always use minidom and recommend it for these kind of interactions with XML files. You can use the parentNode attribute of an element for this purpose.

import xml.dom.minidom as parser

tree = parser.parse('xml.xml')

#let's say we want the first instance of a tag with an specific name
x = tree.getElementsByTagName('tagname')[0]

level = 0
while x:
    x = x.parentNode
    level += 1

print(level)

This is a link to minidom documentation.

jurgenreza
  • 5,856
  • 2
  • 25
  • 37