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')