import xml.parsers.expat
import sys

class Parser:
  def __init__(self,fp):
    self.fp = fp

  def init_tree(self,tree):
    self.tree = tree
    self.deep = -1
    self.ntree = len(tree)
    self.found = -1
    self.name = []  # Debug info
    self.meta    = {}  # Current meta information
    self.data    = ""  # Current data found
    self.address = []  # Current address
    self.metas     = []  # List of meta informations
    self.datas     = []  # List of data found
    self.addresses = []  # Addresses of tag in the tree

  # 3 handler functions
  def start_element(self, name, attrs):
    self.deep += 1
    self.name.append(name)  # Debug info
    #
    if (self.found == self.deep-1) and \
       (self.deep < self.ntree) and \
       (name == self.tree[self.deep]):
      # The upper level was correct, the current level is now correct
      self.found = self.deep
    else:
      return
    #
    self.meta = attrs
    #
    if self.deep < self.ntree:
      if (self.deep+1 == len(self.address)):  # self.deep numbered from 0
        # We already found another tag with the same name at the same depth
        # => increment
        self.address[self.deep] += 1
      else:
        # Found the correct tag at the correct depth. This is the first
        # one.
        self.address.append(1)

  def end_element(self, name):
    if self.found == self.deep:
      if self.found == self.ntree-1:
        # We are at the deepest requested level. Save the values.
        self.metas.append(self.meta)
        self.datas.append(self.data)
        self.addresses.append(list(self.address))  # Append a copy
        self.meta = {}
        self.data = ""
      # We are leaving a valid level
      self.found -= 1
    if self.deep == len(self.address)-2:
      # We are jumping up, remove the depth below.
      self.address.pop()
    self.deep -= 1
    self.name.pop()  # Debug info

  def char_data(self, data):
    # print 'Character data:', self.name  # Debug
    # print 'Character data:', repr(data)
    if self.found == self.deep:
      if self.found == self.ntree-1:
        # We are at the deepest requested level. Save the values.
        self.data += str(data)

  def do(self,tree):
    self.fp.seek(0)
    self.p = xml.parsers.expat.ParserCreate()
    self.p.StartElementHandler = self.start_element
    self.p.EndElementHandler = self.end_element
    self.p.CharacterDataHandler = self.char_data
    #
    self.init_tree(tree)
    #
    self.p.ParseFile(self.fp)
    #
    return (self.addresses,self.metas,self.datas)


def display(l1,l2):
  for i in range(len(l1)):
    print(i,':')
    print('   ',l1[i])
    print('   ',repr(l2[i]))
