def safe_xml_tag_name(
    name: str, numeric_prefix: str = "tag-", empty_fallback: str = "empty-tag"
) -> str:
    """
    Returns a safe xml tag name by replacing invalid characters with a dash.

    :param name: The name that must be converted to a safe xml tag name.
    :param numeric_prefix: An xml tag name can't start with a number, so if that is
        the case, then this value will be prepended.
    :param empty_fallback: An xml tag name can't be empty, so if that is the case,
        then this fallback value will be returned.
    :return: A safe name that can be used as xml tag.
    """

    safe_name = ""

    for char in name:
        if char.isalnum():
            safe_name += char
        else:
            safe_name += "-"

    while "--" in safe_name:
        safe_name = safe_name.replace("--", "-")

    if safe_name.startswith("-"):
        safe_name = safe_name[1:]

    if safe_name.endswith("-"):
        safe_name = safe_name[:-1]

    if len(safe_name) > 0 and safe_name[0].isnumeric():
        safe_name = f"{numeric_prefix}{safe_name}"

    if len(safe_name) == 0:
        return empty_fallback

    return safe_name