How to copy multiple XML nodes to another file in Python

Bare in mind I am very new to Python. I'm trying to copy few XML nodes from sample1.xml to out.xml if it doesn't exist in sample2.xml.

<strong>this is how far I got before I'm stuck</strong>

import xml.etree.ElementTree as ET tree = ET.ElementTree(file='sample1.xml') addtree = ET.ElementTree(file='sample2.xml') root = tree.getroot() addroot = addtree.getroot() for adel in addroot.findall('.//cars/car'): for el in root.findall('cars/car'): with open('out.xml', 'w+') as f: f.write("BEFORE\n") f.write(el.tag) f.write("\n") f.write(adel.tag) f.write("\n") f.write("\n") f.write("AFTER\n") el = adel f.write(el.tag) f.write("\n") f.write(adel.tag)

I have no idea what I'm missing, but it's only copying the actual "tag" itself.

<strong>outputs this:</strong>

BEFORE car car AFTER car car

So I'm missing the children nodes, and also the <, >, </, > tags. Expected result is below.


<cars> <car> <use-car>0</use-car> <use-gas>0</use-gas> <car-name /> <car-key /> <car-location>hawaii</car-location> <car-port>5</car-port> </car> </cars>


<cars> <old> 1 </old> <new> 8 </new> <car /> </cars>

<strong>expected result in out.xml (final product)</strong>

<cars> <old> 1 </old> <new> 8 </old> <car> <use-car>0</use-car> <use-gas>0</use-gas> <car-name /> <car-key /> <car-location>hawaii</car-location> <car-port>5</car-port> </car> </cars>

All the other nodes old and new must remain untouched. I'm just trying to replace <car /> with all its children and grandchildren (if existed) nodes.


<strong>First</strong>, a couple of trivial issues with your XML:

    <li><strong>sample1</strong>: The closing cars tag is missing a /</li> <li><strong>sample2</strong>: The closing new tag incorrectly reads old, should read new</li> </ul>

    <strong>Second</strong>, a disclaimer: my solution below has its limitations - in particular, it wouldn't handle repeatedly substituting the car node from <strong>sample1</strong> into multiple spots in <strong>sample2</strong>. But it works fine for the sample files you've supplied.

    <strong>Third</strong>: thanks to the top couple of answers on access ElementTree node parent node - they informed the implementation of get_node_parent_info below.

    <strong>Finally</strong>, the code:

    import xml.etree.ElementTree as ET def find_child(node, with_name): """Recursively find node with given name""" for element in list(node): if element.tag == with_name: return element elif list(element): sub_result = find_child(element, with_name) if sub_result is not None: return sub_result return None def replace_node(from_tree, to_tree, node_name): """ Replace node with given node_name in to_tree with the same-named node from the from_tree """ # Find nodes of given name ('car' in the example) in each tree from_node = find_child(from_tree.getroot(), node_name) to_node = find_child(to_tree.getroot(), node_name) # Find where to substitute the from_node into the to_tree to_parent, to_index = get_node_parent_info(to_tree, to_node) # Replace to_node with from_node to_parent.remove(to_node) to_parent.insert(to_index, from_node) def get_node_parent_info(tree, node): """ Return tuple of (parent, index) where: parent = node's parent within tree index = index of node under parent """ parent_map = {c:p for p in tree.iter() for c in p} parent = parent_map[node] return parent, list(parent).index(node) from_tree = ET.ElementTree(file='sample1.xml') to_tree = ET.ElementTree(file='sample2.xml') replace_node(from_tree, to_tree, 'car') # ET.dump(to_tree) to_tree.write('output.xml')

    <strong>UPDATE</strong>: It was recently brought to my attention that the implementation of find_child() in the solution I originally supplied would fail if the "child" in question was not in the first branch of the XML tree that was traversed. I've updated the implementation above to rectify this.


  • Rails time zone from URL params
  • Angular 2 - Bootstrap (Ng2-Bootstrap) typeahead implementation
  • Pull to refresh in Angular Js
  • Layout with 'maps' package
  • dplyr idiom for “select A, B, max(C) from D group by C”
  • When is it better for an assembler to use sign extended relocation like R_X86_64_32S instead of zero
  • ARM MOV and MVN operand
  • PHP Handling Namespace with SimpleXML
  • Angular2 emit event up to the DOM tree
  • Firebase, only get new children
  • Excel VBA How to populate a multi-dimensional (3d) array with values from multiple excel ranges?
  • CORS with socket.io
  • Magento get URL before current
  • Prevent Tomcat from caching request during starup
  • How to disable all widgets inside Panel or inside Composite?
  • Zoom in and out of jPanel
  • presentShareDialogWithParams posts to FB wall, but callback handler results say error
  • Access Android Market through SSH tunnel
  • Firefox Extension - Monitor refresh and change of tab
  • Saving Changes After In-App Purchase Has Been Purchased
  • How to run “Deployd” on port 80 instead of port 5000 in webserver.
  • PHP buffered output depending on server setting?
  • Functions in global context
  • how to adjust image in a panel in Java swing?
  • MongoDB in PHP using aggregate to group by _id is null not working
  • Why value captured by reference in lambda is broken? [duplicate]
  • Is possible to count alias result on mysql
  • Possible to stop flickering java tooltip in heavyweight mode?
  • Check if a string to interpolate provides expected placeholders
  • To display the title for the current loaction in map in iphone
  • XCode can't find symbols for a specific iOS library/framework project
  • JTable with a ScrollPane misbehaving
  • Why joiner is not used after Sequence generator or Update statergy
  • Getting Messege Twice Using IMvxMessenger
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Recursive/Hierarchical Query Using Postgres
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • UserPrincipal.Current returns apppool on IIS
  • java string with new operator and a literal