Searches for a sub-element named after element_name in the parsed element,
    and if it exists, removes them all and returns them as a list.
    If clear_empty is True, removes empty parents if all children are removed.
    :see: remove_empty_element(parent_to_parse, element_path, target_element=None)
    :see: get_element(parent_to_parse, element_path)

def remove_element(parent_to_parse, element_path, clear_empty=False):
    """
    Searches for a sub-element named after element_name in the parsed element,
    and if it exists, removes them all and returns them as a list.
    If clear_empty is True, removes empty parents if all children are removed.
    :see: remove_empty_element(parent_to_parse, element_path, target_element=None)
    :see: get_element(parent_to_parse, element_path)
    """

    element = get_element(parent_to_parse)
    removed = []

    if element is None or not element_path:
        return None

    if element_exists(element, element_path):
        if XPATH_DELIM not in element_path:
            for subelem in get_elements(element, element_path):
                removed.append(subelem)
                element.remove(subelem)
        else:
            xpath_segments = element_path.split(XPATH_DELIM)
            parent_segment = XPATH_DELIM.join(xpath_segments[:-1])
            last_segment = xpath_segments[-1]

            for parent in get_elements(element, parent_segment):
                rem = remove_element(parent, last_segment)
                removed.extend(rem if isinstance(rem, list) else [rem])

            if clear_empty:
                removed.extend(remove_empty_element(element, parent_segment))

    return removed[0] if len(removed) == 1 else (removed or None)