code: def _generate_data(schema, elements, attributes=None, path=None):
      
      path = path or []
      attributes = attributes or {}
      tag_name = schema[0]
      data = [tag_name]
      if attributes:
          data.append(attributes)
      new_path = path[:]
      new_path.append(tag_name)
      root = new_path[0]
      possible_paths = ["__".join(new_path), tag_name]
      if root != tag_name and tag_name.startswith(root):
          possible_paths.append(tag_name.lstrip(root)[1:])
      for possible_path in possible_paths:
          val = elements.get(possible_path)
          if val:
              if isinstance(val, (tuple, list)):
                  data = tuple(val)
              else:
                  if attributes:
                      data = (tag_name, attributes, val)
                  else:
                      data = (tag_name, val)
              return tuple(data)
      for subschema in schema[1:]:
          subel = _generate_data(subschema, elements, path=new_path)
          if (not subel) or (subel == subschema):
              continue
          if all(map(lambda x: isinstance(x, tuple), subel)):
              for subsubel in subel:
                  data.append(subsubel)
          elif not el_is_empty(subel):
              data.append(subel)
      return tuple(data)
docs: Using tree-as-tuple ``schema`` as guide, return a tree-as-tuple ``data``
      representing a PREMIS XML element, where the values in dict ``elements`` and
      the values in dict ``attributes`` are located in the appropriate locations
      in the ``data`` tree structure.