def xml_key_extractor()

in azext_iot/sdk/deviceupdate/dataplane/_serialization.py [0:0]


def xml_key_extractor(attr, attr_desc, data):
    if isinstance(data, dict):
        return None

    # Test if this model is XML ready first
    if not isinstance(data, ET.Element):
        return None

    xml_desc = attr_desc.get('xml', {})
    xml_name = xml_desc.get('name', attr_desc['key'])

    # Look for a children
    is_iter_type = attr_desc['type'].startswith("[")
    is_wrapped = xml_desc.get("wrapped", False)
    internal_type = attr_desc.get("internalType", None)
    internal_type_xml_map = getattr(internal_type, "_xml_map", {})

    # Integrate namespace if necessary
    xml_ns = xml_desc.get('ns', internal_type_xml_map.get("ns", None))
    if xml_ns:
        xml_name = "{}{}".format(xml_ns, xml_name)

    # If it's an attribute, that's simple
    if xml_desc.get("attr", False):
        return data.get(xml_name)

    # If it's x-ms-text, that's simple too
    if xml_desc.get("text", False):
        return data.text

    # Scenario where I take the local name:
    # - Wrapped node
    # - Internal type is an enum (considered basic types)
    # - Internal type has no XML/Name node
    if is_wrapped or (internal_type and (issubclass(internal_type, Enum) or 'name' not in internal_type_xml_map)):
        children = data.findall(xml_name)
    # If internal type has a local name and it's not a list, I use that name
    elif not is_iter_type and internal_type and 'name' in internal_type_xml_map:
        xml_name = _extract_name_from_internal_type(internal_type)
        children = data.findall(xml_name)
    # That's an array
    else:
        if internal_type: # Complex type, ignore itemsName and use the complex type name
            items_name = _extract_name_from_internal_type(internal_type)
        else:
            items_name = xml_desc.get("itemsName", xml_name)
        children = data.findall(items_name)

    if len(children) == 0:
        if is_iter_type:
            if is_wrapped:
                return None # is_wrapped no node, we want None
            else:
                return [] # not wrapped, assume empty list
        return None  # Assume it's not there, maybe an optional node.

    # If is_iter_type and not wrapped, return all found children
    if is_iter_type:
        if not is_wrapped:
            return children
        else: # Iter and wrapped, should have found one node only (the wrap one)
            if len(children) != 1:
                raise DeserializationError(
                    "Tried to deserialize an array not wrapped, and found several nodes '{}'. Maybe you should declare this array as wrapped?".format(
                        xml_name
                    ))
            return list(children[0])  # Might be empty list and that's ok.

    # Here it's not a itertype, we should have found one element only or empty
    if len(children) > 1:
        raise DeserializationError("Find several XML '{}' where it was not expected".format(xml_name))
    return children[0]