from lxml import etree from copy import deepcopy def insert_after(anchor_name: str, elem_name: str): file_path = "../decompiled/res/values/public.xml" parser = etree.XMLParser(remove_blank_text=True) tree = etree.parse(file_path, parser) root = tree.getroot() anchor = None types = {} for idx, elem in enumerate(root): assert elem.tag == "public" assert elem.keys() == ["type", "name", "id"] attrs = dict(zip(elem.keys(), elem.values())) if attrs["name"] == anchor_name: assert anchor == None anchor = (elem, attrs) types[attrs["type"]] = types.get(attrs["type"], []) + [int(attrs["id"], 16)] free_ids = set() group = types[anchor[1]["type"]] for i in range(min(group), max(group) + 1): if i not in group: free_ids.add(i) assert len(free_ids) > 0 new_id = None for i in free_ids: if i > int(anchor[1]["id"], 16): new_id = i break if new_id == None: new_id = max(group) + 1 for name, group in types.items(): if name == anchor[1]["type"]: continue if new_id in group: new_id = max(group) new_elem = deepcopy(anchor[0]) new_elem.set("id", new_id) new_elem.set("name", elem_name) anchor[0].addnext(new_elem) tree.write(file_path, pretty_print=True, xml_declaration=True, encoding="utf-8") return new_id