input: Write a function to parse an XML document and return a list of tag objects. If the XML document is empty or has no tags, return an empty list. The function should be able to handle nested tags and extract their attributes.
  assert parse_xml('<xml><root><child1 id="1"><subchild1 value="a"></subchild1><subchild2 value="b"></subchild2></child1><child2 id="2"><subchild3 value="c"></subchild3><subchild4 value="d"></subchild4></child2></root></xml>')==[Tag('1', ['a', 'b']), Tag('2', ['c', 'd'])]
  assert parse_xml('<xml></xml>')==[]
  assert parse_xml('<xml><root></root></xml>')==[]
  assert parse_xml('<xml><root><child1 id="1"><subchild1 value="x"></subchild1></child1><child2 id="2"><subchild2 value="y"></subchild2></child2></root></xml>')==[Tag('1', ['x']), Tag('2', ['y'])]
  assert parse_xml('<xml><root><child1 id="1"><subchild1 value="a"></subchild1><subchild2 value="b"></subchild2></child1><child2 id="2"></child2></root></xml>')==[Tag('1', ['a', 'b']), Tag('2', [])]
output: def parse_xml(xml_str):
      from xml.etree import ElementTree as ET
      root = ET.fromstring(xml_str)
      tags = []
      
      def extract_tags(element):
          tag_info = {}
          for child in element:
              if 'id' in child.attrib:
                  tag_id = child.attrib['id']
                  values = []
                  for subchild in child:
                      if 'value' in subchild.attrib:
                          values.append(subchild.attrib['value'])
                  if tag_id not in tag_info:
                      tag_info[tag_id] = []
                  tag_info[tag_id].extend(values)
              extract_tags(child)
          return tag_info
      
      tag_info = extract_tags(root)
      for tag_id, values in tag_info.items():
          tags.append(Tag(tag_id, values))
      
      return tags