import xml.etree.ElementTree as ET import copy import argparse import os class STP_FILE_MERGER: def __init__(self): self.stp_out_xml_tree = None self.stp_instance_index = 0 self.stp_instance_names = set() def write(self, stp_out): print( "Writing " + stp_out ) self.stp_out_xml_tree.write( stp_out ) def merge(self, stp_in): print( "Merging " + stp_in ) stp_in_xml_tree = ET.parse( stp_in ) self.__adjust_instance(stp_in_xml_tree, stp_in) if (not self.stp_out_xml_tree): self.stp_out_xml_tree = copy.deepcopy( stp_in_xml_tree ) else: self.__copy_instances( stp_in_xml_tree ) self.__copy_display_tree( stp_in_xml_tree ) def __adjust_instance(self, stp_in_xml_tree, stp_in): for inst_xml in stp_in_xml_tree.getroot().findall( "./instance" ): inst_name = inst_xml.get( "name" ) # Fix up instance name in case of duplicates if ( inst_name in self.stp_instance_names ): new_inst_name = inst_name + "_" + stp_in.rstrip( ".stp" ) print( " Warning: Instance name conflict is found. Instance name is changed from " + inst_name + " to " + new_inst_name ) self.__adjust_instance_name_reference( stp_in_xml_tree, inst_name, new_inst_name ) inst_xml.set( "name", new_inst_name ) inst_name = new_inst_name self.stp_instance_names.add( inst_name ) # reassign instance index sequentially inst_info_xml = inst_xml.find( "./node_ip_info" ) inst_info_xml.set( "instance_id", str(self.stp_instance_index) ) self.stp_instance_index += 1 def __adjust_instance_name_reference(self, stp_in_xml_tree, old_name, new_name): for branch_xml in stp_in_xml_tree.getroot().findall( "./display_tree/display_branch" ): inst_name = branch_xml.get( "instance" ) if ( inst_name == old_name ): branch_xml.set( "instance", new_name ) return def __copy_instances(self, stp_in_xml_tree): for inst_xml in stp_in_xml_tree.getroot().findall( "./instance" ): new_inst_xml = copy.deepcopy( inst_xml ) self.stp_out_xml_tree.getroot().append( new_inst_xml ) def __copy_display_tree(self, stp_in_xml_tree): display_tree_xml = self.stp_out_xml_tree.getroot().find( "./display_tree" ) for display_branch_xml in stp_in_xml_tree.findall( "./display_tree/display_branch" ): new_display_branch_xml = copy.deepcopy( display_branch_xml ) display_tree_xml.append( new_display_branch_xml ) def main(): parser = argparse.ArgumentParser(description='Merge instances from multiple .stp files into one .stp file.') parser.add_argument('stp_files', metavar='stp_file_in', type=str, nargs='+', help='an .stp file name') parser.add_argument('-o', '--merged_stp_file', nargs=1, required=True, help='merged output .stp file') args = parser.parse_args() merged_stp_file = args.merged_stp_file[0] stp_files = args.stp_files stp_merger = STP_FILE_MERGER() for stp_file in stp_files: stp_merger.merge( stp_file ) stp_merger.write( merged_stp_file ) if __name__ == "__main__": # execute only if run as a script main()