def update_complex(tree_to_update, xpath_root, xpath_map, prop, values): """ Updates and returns the updated complex Element parsed from tree_to_update. :param tree_to_update: the XML tree compatible with element_utils to be updated :param xpath_root: the XPATH location of the root of the complex Element :param xpath_map: a Dictionary of XPATHs corresponding to the complex structure definition :param prop: the property identifying the complex structure to be serialized :param values: a Dictionary representing the complex structure to be updated """ remove_element(tree_to_update, xpath_root, True) values = reduce_value(values, {}) if not values: # Returns the elements corresponding to property removed from the tree updated = update_property(tree_to_update, xpath_root, xpath_root, prop, values) else: for subprop, value in iteritems(values): xpath = xpath_map[subprop] value = get_default_for_complex_sub(prop, subprop, value, xpath) update_property(tree_to_update, None, xpath, subprop, value) updated = get_element(tree_to_update, xpath_root) return updated
def update_element(elem, idx, root, path, vals): """ Internal helper function to encapsulate single item update """ has_root = bool(root and len(path) > len(root) and path.startswith(root)) path, attr = get_xpath_tuple(path) # 'path/@attr' to ('path', 'attr') if attr: removed = [get_element(elem, path)] remove_element_attributes(removed[0], attr) elif not has_root: removed = wrap_value(remove_element(elem, path)) else: path = get_xpath_branch(root, path) removed = [] if idx != 0 else [remove_element(e, path, True) for e in get_elements(elem, root)] if not vals: return removed items = [] for i, val in enumerate(wrap_value(vals)): elem_to_update = elem if has_root: elem_to_update = insert_element(elem, (i + idx), root) val = val.decode('utf-8') if not isinstance(val, string_types) else val if not attr: items.append(insert_element(elem_to_update, i, path, val)) else: items.append(insert_element(elem_to_update, i, path, **{attr: val})) return items
def update_element(elem, idx, root, path, vals): """ Internal helper function to encapsulate single item update """ has_root = bool(root and len(path) > len(root) and path.startswith(root)) path, attr = get_xpath_tuple(path) # 'path/@attr' to ('path', 'attr') if attr: removed = [get_element(elem, path)] remove_element_attributes(removed[0], attr) elif not has_root: removed = wrap_value(remove_element(elem, path)) else: path = get_xpath_branch(root, path) removed = [] if idx != 0 else [ remove_element(e, path, True) for e in get_elements(elem, root) ] if not vals: return removed items = [] for i, val in enumerate(wrap_value(vals)): elem_to_update = elem if has_root: elem_to_update = insert_element(elem, (i + idx), root) val = val.decode('utf-8') if not isinstance(val, string_types) else val if not attr: items.append(insert_element(elem_to_update, i, path, val)) elif path: items.append( insert_element(elem_to_update, i, path, **{attr: val})) else: set_element_attributes(elem_to_update, **{attr: val}) items.append(elem_to_update) return items