From 53580f8af4c7763ec869f0c5aba0d3658729871c Mon Sep 17 00:00:00 2001 From: Klaus Thoden Date: Wed, 21 Nov 2018 17:27:07 +0100 Subject: [PATCH] Introducing XML helper functions --- libeoaconvert.py | 126 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/libeoaconvert.py b/libeoaconvert.py index 90b2658..933a9e3 100644 --- a/libeoaconvert.py +++ b/libeoaconvert.py @@ -256,3 +256,129 @@ def debug_xml_here(xml_tree, xml_filename): xml_tree.write(xml_path, pretty_print=True, xml_declaration=True,encoding="utf-8") logging.info("Wrote %s." % xml_path) # def debug_xml_here ends here + +def wrap_into_element(wrapper, wrappee): + """Wrap an existing element into a new one""" + + old_tail = wrappee.tail + wrappee.tail = "" + wrappee.addprevious(wrapper) + wrapper.insert(0, wrappee) + wrapper.tail = old_tail + + return +# def wrap_into_element ends here + +def remove_wrapping_element(wrapper): + """Put child elements one level up and delete surrounding element""" + + wrappees = wrapper.getchildren() + wrapper_parent = wrapper.getparent() + + wrapper_text = wrapper.text + if wrapper_text is not None: + wrapper_text = wrapper_text.strip() + if len(wrapper_text) > 0: + logging.warning("Wrapping element contains text: %s", wrapper_text) + wrapper_tail = wrapper.tail + if wrapper_tail is not None: + wrapper_tail = wrapper_tail.strip() + if len(wrapper_tail) > 0: + logging.warning("Wrapping element contains has tail: %s", wrapper_tail) + + wrapper_pos = wrapper_parent.index(wrapper) + insert_position = wrapper_parent.index(wrapper) + insertioncounter = insert_position + for child in wrappees: + wrapper_parent.insert(insertioncounter, child) + insertioncounter += 1 + + wrapper.clear() + wrapper_parent.remove(wrapper) + + return +# def remove_wrapping_element ends here + +def change_attribute_name(element, attribute, newname, add_hash=False): + """Change name of an XML attribute, but retain value""" + + attribute_value = element.get(attribute) + if attribute_value is not None: + if add_hash is True: + attribute_value = "#" + attribute_value + else: + pass + element.set(newname, attribute_value) + del element.attrib[attribute] + else: + # logging.warning("No attribute %s found.", attribute) + pass + + return +# def change_attribute_name ends here + +def transfer_xml_attributes(old_element_attributes, new_element): + """Transfer the attributes of one element to another element. + + Expects the old elements in dictionary form""" + + for attrib in old_element_attributes: + new_element.attrib[attrib] = old_element_attributes[attrib] + + return +# def transfer_xml_attributes ends here + +def split_with_milestone_element(element, milestone, splitter): + """Split the text of an element by inserting milestone tags.""" + + element_text = element.text + textparts = element_text.split(splitter) + + element_attributes = element.attrib + element.clear() + + element.text = textparts[0] + splitter + + for part in textparts[1:-1]: + lb_element = etree.Element(milestone) + lb_element.tail = part + splitter + element.append(lb_element) + + lb_element = etree.Element(milestone) + lb_element.tail = textparts[-1] + element.append(lb_element) + transfer_xml_attributes(element_attributes, element) + + return +# def split_with_milestone_element ends here + +def get_place_in_xml_tree(element, tree): + """Find out the position of an element in a tree. + + Return the index. Example: how to insert an element after a specific + element + """ + + xml_children = tree.getchildren() + position = xml_children.index(element) + + return position +# def get_place_in_xml_tree ends here + +def insert_after(new_element, preceding, before=False): + """Insert an element after another + + Optional keyword argument inserts element before + """ + + parent_element = preceding.getparent() + context_children = parent_element.getchildren() + preceding_position = context_children.index(preceding) + if before: + insertion_point = preceding_position + else: + insertion_point = preceding_position + 1 + parent_element.insert(insertion_point, new_element) + + return +# def insert_after ends here