def _assert_tag_and_attributes_are_equal(xml1, xml2, can_extend=False):
    if xml1.tag != xml2.tag:
        raise AssertionError(u'Tags do not match: {tag1} != {tag2}'.format(
            tag1=_describe_element(xml1), tag2=_describe_element(xml2)
        ))

    added_attributes = set(xml2.attrib).difference(xml1.attrib)
    missing_attributes = set(xml1.attrib).difference(xml2.attrib)

    if missing_attributes:
        raise AssertionError(u'Second xml misses attributes: {path}/({attributes})'.format(
            path=_describe_element(xml2), attributes=','.join(missing_attributes)
        ))

    if not can_extend and added_attributes:
        raise AssertionError(u'Second xml has additional attributes: {path}/({attributes})'.format(
            path=_describe_element(xml2), attributes=','.join(added_attributes)
        ))

    for attrib in xml1.attrib:
        if not _xml_compare_text(xml1.attrib[attrib], xml2.attrib[attrib], False):
            raise AssertionError(u"Attribute values are not equal: {path}/{attribute}['{v1}' != '{v2}']".format(
                path=_describe_element(xml1), attribute=attrib, v1=xml1.attrib[attrib], v2=xml2.attrib[attrib]
            ))

    if not _xml_compare_text(xml1.text, xml2.text, True):
        raise AssertionError(u"Tags text differs: {path}['{t1}' != '{t2}']".format(
            path=_describe_element(xml1), t1=xml1.text, t2=xml2.text
        ))

    if not _xml_compare_text(xml1.tail, xml2.tail, True):
        raise AssertionError(u"Tags tail differs: {path}['{t1}' != '{t2}']".format(
            path=_describe_element(xml1), t1=xml1.tail, t2=xml2.tail
        ))