from Base.Arxml import Arxml import logging import copy class BaseContainer: def __init__(self, element): self.__element = element # self.__container_tag = '' # self.__container_attribute = {} # self.__container_text = '' self.set_container_attr() # print(self.get_container_attr()) def set_container_attr(self): if self.__element is not None: self.__container_tag = self.__element.tag self.__container_attribute = self.__element.attrib self.__container_text = self.__element.text else: self.__container_tag = '' self.__container_attribute = {} self.__container_text = '' def __str__(self): container = 'Container Tag:{}, Attribute:{}, Text:{}'.format(self.__container_tag, self.__container_attribute, self.__container_text) return container def update_container_by_attr(self, attr_dict): pass def get_container_attr(self): attr_dict = {} attr_dict['TAG'] = self.__container_tag.split('}')[-1] attr_dict['ATTRIB'] = self.__container_attribute.get('DEST', '') attr_dict['TEXT'] = self.__container_text return attr_dict class EcucContainerValue: ''' short_name container_definition_ref: (attrib_type, definition_text) parameter_values: { split(parameter_name):(tag_type, parameter_attrib_type, parameter_name, parameter_value), ... } reference_values: { split(reference_name):(tag_type, reference_name_attrib_type, reference_name, reference_value_attrib_type, reference_value), ... } eg: { 'short_name': 'CCP_SigGW_050ms_PDU00_PT_8c62d7ea_Tx', 'container_definition_ref': ['ECUC-PARAM-CONF-CONTAINER-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu'], 'parameter_values': { 'IpduMContainedPduHeaderId': ['ECUC-NUMERICAL-PARAM-VALUE', 'ECUC-INTEGER-PARAM-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedPduHeaderId', '1114112'], 'IpduMContainedTxPduCollectionSemantics': ['ECUC-TEXTUAL-PARAM-VALUE', 'ECUC-ENUMERATION-PARAM-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedTxPduCollectionSemantics', 'IPDUM_COLLECT_LAST_IS_BEST'], 'IpduMContainedTxPduTrigger': ['ECUC-TEXTUAL-PARAM-VALUE', 'ECUC-ENUMERATION-PARAM-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedTxPduTrigger', 'IPDUM_TRIGGER_ALWAYS'], 'IpduMContainedTxPduConfirmation': ['ECUC-NUMERICAL-PARAM-VALUE', 'ECUC-BOOLEAN-PARAM-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedTxPduConfirmation', 'true'], 'IpduMContainedTxPduHandleId': ['ECUC-NUMERICAL-PARAM-VALUE', 'ECUC-INTEGER-PARAM-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedTxPduHandleId', '43'] }, 'reference_values': { 'IpduMContainedTxInContainerPduRef': ['ECUC-REFERENCE-VALUE', 'ECUC-REFERENCE-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedTxInContainerPduRef', 'ECUC-CONTAINER-VALUE', '/ActiveEcuC/IpduM/IpduMConfig/CCP_PTCANFD_050ms_Container03_52bb19c8_Tx'], 'IpduMContainedTxPduRef': ['ECUC-REFERENCE-VALUE', 'ECUC-REFERENCE-DEF', '/MICROSAR/IpduM/IpduMConfig/IpduMContainedTxPdu/IpduMContainedTxPduRef', 'ECUC-CONTAINER-VALUE', '/ActiveEcuC/EcuC/EcucPduCollection/CCP_SigGW_050ms_PDU00_PT_8c62d7ea_Tx'] } } ''' def __init__(self, ecuc_container): self.__ecuc_container = ecuc_container self.__get_ecuc_container_attr() def __get_ecuc_container_attr(self): ''' 获取一个ECUC-CONTAINER-VALUE container中的所有属性,使用成员变量,存储属性字典,和子container :return: ''' # SHORT-NAME container short_name_container = Arxml.get_first_match_element(self.__ecuc_container, './SHORT-NAME') short_name = Arxml.get_container_text(short_name_container) # DEFINITION-REF container definition_container = Arxml.get_first_match_element(self.__ecuc_container, './DEFINITION-REF') definition_container_attr = BaseContainer(definition_container).get_container_attr() # print(definition_container_attr) # DEST attribute and container text container_definition_ref = [definition_container_attr['ATTRIB'], definition_container_attr['TEXT']] ''' PARAMETER-VALUES [ECUC-NUMERICAL-PARAM-VALUE]-0 DEFINITION-REF [/MICROSAR/CanIf/CanIfInitCfg/CanIfBufferCfg/CanIfBufferSize]-2 DEST [ECUC-INTEGER-PARAM-DEF]-1 VALUE [0]-3 ''' # PARAMETER-VALUES container parameter_containers = Arxml.get_first_match_element(self.__ecuc_container, './PARAMETER-VALUES') if parameter_containers is None: # fix,when get parameter_containers is None, for iterator will get ERROR parameter_containers = [] parameter_values = {} parameter_containers_dict = {} for ele in parameter_containers: # parameter container tag is parameter type tag_type = BaseContainer(ele).get_container_attr()['TAG'] # parameter DEFINITION-REF container , include attribute, text(parameter name), tag(DEFINITION-REF) def_container = Arxml.get_first_match_element(ele, './DEFINITION-REF') def_attr = BaseContainer(def_container).get_container_attr() parameter_attrib_type = def_attr['ATTRIB'] parameter_name = def_attr['TEXT'] parameter_name_short = parameter_name.split('/')[-1] # parameter VALUE container , include attribute, text(actual parameter value), tag(VALUE) value_container = Arxml.get_first_match_element(ele, './VALUE') value_attr = BaseContainer(value_container).get_container_attr() ## get text info parameter_value = value_attr['TEXT'] parameter_values[parameter_name_short] = [tag_type, parameter_attrib_type, parameter_name, parameter_value] parameter_containers_dict[parameter_name_short] = ele #reference container reference_containers = Arxml.get_first_match_element(self.__ecuc_container, './REFERENCE-VALUES') if reference_containers is None: # fix,when get reference_containers is None, for iterator will get ERROR reference_containers = [] ''' REFERENCE-VALUES [ECUC-REFERENCE-VALUE]-0 DEFINITION-REF [/MICROSAR/CanIf/CanIfInitCfg/CanIfBufferCfg/CanIfBufferHthRef]-2 DEST [ECUC-REFERENCE-DEF]-1 VALUE-REF [/ActiveEcuC/CanIf/CanIfInitCfg/CanIfInitHohCfg/CanIfHthCfg_CCP_ADCANFD_010ms_Container36_574ce325_Tx]-4 DEST [ECUC-CONTAINER-VALUE]-3 ''' reference_values = {} reference_containers_dict = {} for ele in reference_containers: tag_type = BaseContainer(ele).get_container_attr()['TAG'] def_container = Arxml.get_first_match_element(ele, './DEFINITION-REF') def_attr = BaseContainer(def_container).get_container_attr() reference_name_attrib_type = def_attr['ATTRIB'] reference_name = def_attr['TEXT'] reference_name_short = reference_name.split('/')[-1] value_container = Arxml.get_first_match_element(ele, './VALUE-REF') # difference with parameter container value_attr = BaseContainer(value_container).get_container_attr() reference_value = value_attr['TEXT'] reference_value_attrib_type = value_attr['ATTRIB'] reference_values[reference_name_short] = [tag_type, reference_name_attrib_type, reference_name, reference_value_attrib_type, reference_value] reference_containers_dict[reference_name_short] = ele self.__container_attr = { 'short_name':short_name, 'container_definition_ref':container_definition_ref, 'parameter_values':parameter_values, 'reference_values':reference_values } self.__container = { 'short_name': short_name_container, 'container_definition_ref': definition_container, 'parameter_values': parameter_containers_dict, 'reference_values': reference_containers_dict } @property def container_attr(self): return copy.deepcopy(self.__container_attr) @container_attr.setter def container_attr(self, new_conatiner_attr): self.__container_attr = new_conatiner_attr def __update_ecuc_base_attr(self, new_attr): pass def __update_ecuc_base_container_attr(self, new_attr, container_type): value_tag_name = 'VALUE' if 'PARAM' == container_type else 'VALUE-REF' attr_key = 'parameter_values' if 'PARAM' == container_type else 'reference_values' if len(new_attr[attr_key]) >= len(self.__container_attr[attr_key]) and \ new_attr[attr_key] != self.__container_attr[attr_key]: for key, value in new_attr[attr_key].items(): logging.info(key) logging.info(value) if key in self.__container_attr[attr_key]: ## param or reference key in attr dict? yes # find param VALUE or reference VALUE-REF element value_container = Arxml.get_first_match_element(self.__container[attr_key][key], './' + value_tag_name) # print(value_container) if value_container is not None: # VALUE or reference VALUE-REF element is exit, so update value. value_container.text = value[-1] # set text info # elif value[-1] != '': else: # has key but without VALUE or reference VALUE-REF element. Arxml.creat_child_new_element(self.__container[attr_key][key], # new add element in container, can not find by xpath, through it has append to container value_tag_name, text_str=value[-1]) # TO DO creat VALUE-REF child with attribute_dict pass else: # new attr ,need to be created param_type_tag = value[0] # if or is empty, when add element to it, will cause error. first_container_key = list(self.__container[attr_key].keys())[0] # find first element in or # find first brother container brother_container = self.__container[attr_key][first_container_key] # creat new brother element new_container = Arxml.creat_brother_new_element(brother_container, param_type_tag) # creat child element Arxml.creat_child_new_element(new_container, 'DEFINITION-REF', text_str=value[2], attribute_dict={'DEST':value[1]}) if 'PARAM' == container_type: # creat child element Arxml.creat_child_new_element(new_container, value_tag_name, text_str=value[-1]) else: # creat child element Arxml.creat_child_new_element(new_container, value_tag_name, text_str=value[-1], attribute_dict={'DEST':value[-2]}) # self.__container_attr = new_attr def __update_ecuc_parameter_attr(self, new_attr): self.__update_ecuc_base_container_attr(new_attr, 'PARAM') def __update_ecuc_reference_attr(self, new_attr): self.__update_ecuc_base_container_attr(new_attr, 'REF') def update_ecuc_container(self, new_attr): ''' update info or add new sub-container :param new_attr: :return: ''' self.__update_ecuc_base_attr(new_attr) self.__update_ecuc_parameter_attr(new_attr) self.__update_ecuc_reference_attr(new_attr) self.__container_attr = new_attr if __name__ == '__main__': arxml = Arxml('EH32_GW04_IpduM_ecuc.arxml') element = Arxml.get_first_match_element(arxml.root, './/SHORT-NAME', 'IpduMConfig', 'TEXT_EQ') par_ele = Arxml.get_parent_element(element) # ecuc = Arxml.get_first_match_element(par_ele, './SUB-CONTAINERS/ECUC-CONTAINER-VALUE') # # ecuc_container = EcucContainerValue(ecuc) # attr = ecuc_container.container_attr # attr['parameter_values']['IpduMContainedPduHeaderId'][-1] ='1122' # attr['parameter_values']['aaaa'] = ['test_tag', 'test_attribute', 'test_param_name', 'test_param_value'] # attr['reference_values']['bbbb'] = ['test_ref_tag', 'test_ref_attribute', 'test_ref_name', 'test_ref_value_attrib', 'test_ref_value'] # ecuc_container.update_ecuc_container(attr) ecuc_containers = Arxml.get_all_match_element(par_ele, './SUB-CONTAINERS/ECUC-CONTAINER-VALUE') for ecuc in ecuc_containers: ecuc_container = EcucContainerValue(ecuc) print(ecuc_container.container_attr) arxml.xml_write_to_file(arxml.root, 'test.arxml')