input: Write a function that takes an XML string as input and returns a list of Tag objects. Each Tag object should contain an 'id' attribute from the corresponding XML tag and a list of 'values' extracted from its sub-tags. Assume the XML structure always follows the pattern where each child tag contains 'id' and multiple sub-tags with 'value' attributes.
  
  
  def parse_xml(text):
      tag_objects = []
  
      root = ET.fromstring(text)
      for child in root:
          tag = Tag(child.attrib["id"])
          for subchild in child:
              tag.add_value(subchild.attrib["value"])
          tag_objects.append(tag)
  
      return tag_objects
  
  class Tag:
      def __init__(self, tag_id):
          self.tag_id = tag_id
          self.values = []
      
      def add_value(self, value):
          self.values.append(value)
  
  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>
    <root>
      <child1 id="3">
        <subchild1 value="e"></subchild1>
      </child1>
    </root>
  </xml>""") == [Tag("3", ["e"])]
  assert parse_xml("""<xml></xml>""") == []
  
output: def parse_xml(text):
      tag_objects = []
  
      root = ET.fromstring(text)
      for child in root:
          tag = Tag(child.attrib["id"])
          for subchild in child:
              tag.add_value(subchild.attrib["value"])
          tag_objects.append(tag)
  
      return tag_objects