Python - 遍历目录中的所有 xml 文件,将一个元素及其子元素放在另一个 xml 文件中的正确位置
Python - Go through all xml files in directory, take one element with it's sub-elements and place them at correct spot in another xml file
我在这里有一种情况,我必须浏览一个目录中的所有 xml 个文件:
Get.xml
Set.xml
Try.xml
etc..
它们每个都有类似但不相同的结构,包含如下元素:
<example atrib1='' atrib2= ''...>
<summary atrib1='' atrib2= ''...>
<properties>
</properties>
</summary>
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</example>
但是我还有其他的我们称之为 Main.xml,其中包含 Get、Set、Try 作为其元素的名称:
<example atrib1='' atrib2= ''...>
<summary atrib1='' atrib2= ''...>
<properties>
</properties>
</summary>
<Test name="Get">
</Test>
<Test name="Set">
</Test>
<Test name="Try">
</Test>
</example>
现在我需要像前面提到的那样遍历所有 XML 并获取元素及其子元素,并将其放在 Main.xml 中与当前元素名称匹配的确切位置XML,所以最后应该是:
Main.xml
<example atrib1='' atrib2= ''...>
<summary atrib1='' atrib2= ''...>
<properties>
</properties>
</summary>
<Test name="Get">
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</Test>
<Test name="Set">
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</Test>
<Test name="Try">
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</Test>
</example>
目前我有这对函数正在替换不同 xml 文件中的两个相同元素,但很难修复它所以我可以将整个元素复制到另一个文件的确切位置:
def find_child(node, with_name):
"""Recursively find node with given name"""
for element in list(node):
if element.tag == 'Elem':
return element
elif list(element):
sub_result = find_child(element, 'Elem')
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 in each tree
from_node = find_child(from_tree.getroot(), 'Elem')
to_node = find_child(to_tree.getroot(), 'Test')
# 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)
for filename in files:
from_tree = ET.ElementTree(filename)
to_tree = ET.ElementTree(file='Main.xml')
replace_node(from_tree, to_tree, 'Elem')
ET.dump(to_tree)
to_tree.write('Main.xml')
我知道这行不通,因为我们没有两个可以替换的相同元素,我需要更好的解决方案,请协助!
我也试过类似的方法,只是简单地复制整个元素,但没有成功:
source_tree = ET.parse('Get.xml')
source_root = source_tree.getroot()
dest_tree = ET.parse('Main.xml')
dest_root = dest_tree.getroot()
for element in source_root:
if element.tag == 'Elem':
for delement in dest_root.iter('Test'):
name = delement.get('name')
if name == 'Get':
delement.append(element)
dest_tree.write('Main.xml', encoding='utf-8', xml_declaration=True)
我希望很清楚这里必须做什么..
如果您对如何做到这一点有任何想法,请告诉我!
谢谢!
我不确定这是否是您想要的,但它将所有 Elem 元素插入到正确的测试元素下。
import xml.etree.ElementTree as ET
main_tree = ET.parse('Main.xml')
for test_elem in main_tree.findall('Test'):
tree = ET.parse(f"{test_elem.get('name')}.xml")
for elem in tree.findall("Elem"):
test_elem.append(elem)
with open('newmain.xml', 'wb') as f:
main_tree.write(f)
所以我设法写了这个并且它有效,唯一的问题是它没有打印 xml 作为“漂亮的打印”:
files = os.listdir(#location)
for xml in files:
if xml.endswith('.xml'):
source_tree = ET.parse(xml)
source_root = source_tree.getroot()
dest_tree = ET.parse('Main.xml')
dest_root = dest_tree.getroot()
for element in source_root:
if element.tag == 'Elem':
to_copy = element
for delement in dest_root.iter('Test'):
name = delement.get('name')
if name+'.xml' == xml:
destination_root = delement
destination_root.append(to_copy)
dest_tree.write('Main.xml', encoding='utf-8', xml_declaration=True)
我在这里有一种情况,我必须浏览一个目录中的所有 xml 个文件:
Get.xml
Set.xml
Try.xml
etc..
它们每个都有类似但不相同的结构,包含如下元素:
<example atrib1='' atrib2= ''...>
<summary atrib1='' atrib2= ''...>
<properties>
</properties>
</summary>
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</example>
但是我还有其他的我们称之为 Main.xml,其中包含 Get、Set、Try 作为其元素的名称:
<example atrib1='' atrib2= ''...>
<summary atrib1='' atrib2= ''...>
<properties>
</properties>
</summary>
<Test name="Get">
</Test>
<Test name="Set">
</Test>
<Test name="Try">
</Test>
</example>
现在我需要像前面提到的那样遍历所有 XML 并获取元素及其子元素,并将其放在 Main.xml 中与当前元素名称匹配的确切位置XML,所以最后应该是:
Main.xml
<example atrib1='' atrib2= ''...>
<summary atrib1='' atrib2= ''...>
<properties>
</properties>
</summary>
<Test name="Get">
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</Test>
<Test name="Set">
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</Test>
<Test name="Try">
<Elem>
<element1>
<element2>
<subelement2>
........
</subelement2>
<element2>
<element1>
</Elem>
</Test>
</example>
目前我有这对函数正在替换不同 xml 文件中的两个相同元素,但很难修复它所以我可以将整个元素复制到另一个文件的确切位置:
def find_child(node, with_name):
"""Recursively find node with given name"""
for element in list(node):
if element.tag == 'Elem':
return element
elif list(element):
sub_result = find_child(element, 'Elem')
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 in each tree
from_node = find_child(from_tree.getroot(), 'Elem')
to_node = find_child(to_tree.getroot(), 'Test')
# 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)
for filename in files:
from_tree = ET.ElementTree(filename)
to_tree = ET.ElementTree(file='Main.xml')
replace_node(from_tree, to_tree, 'Elem')
ET.dump(to_tree)
to_tree.write('Main.xml')
我知道这行不通,因为我们没有两个可以替换的相同元素,我需要更好的解决方案,请协助!
我也试过类似的方法,只是简单地复制整个元素,但没有成功:
source_tree = ET.parse('Get.xml')
source_root = source_tree.getroot()
dest_tree = ET.parse('Main.xml')
dest_root = dest_tree.getroot()
for element in source_root:
if element.tag == 'Elem':
for delement in dest_root.iter('Test'):
name = delement.get('name')
if name == 'Get':
delement.append(element)
dest_tree.write('Main.xml', encoding='utf-8', xml_declaration=True)
我希望很清楚这里必须做什么.. 如果您对如何做到这一点有任何想法,请告诉我! 谢谢!
我不确定这是否是您想要的,但它将所有 Elem 元素插入到正确的测试元素下。
import xml.etree.ElementTree as ET
main_tree = ET.parse('Main.xml')
for test_elem in main_tree.findall('Test'):
tree = ET.parse(f"{test_elem.get('name')}.xml")
for elem in tree.findall("Elem"):
test_elem.append(elem)
with open('newmain.xml', 'wb') as f:
main_tree.write(f)
所以我设法写了这个并且它有效,唯一的问题是它没有打印 xml 作为“漂亮的打印”:
files = os.listdir(#location)
for xml in files:
if xml.endswith('.xml'):
source_tree = ET.parse(xml)
source_root = source_tree.getroot()
dest_tree = ET.parse('Main.xml')
dest_root = dest_tree.getroot()
for element in source_root:
if element.tag == 'Elem':
to_copy = element
for delement in dest_root.iter('Test'):
name = delement.get('name')
if name+'.xml' == xml:
destination_root = delement
destination_root.append(to_copy)
dest_tree.write('Main.xml', encoding='utf-8', xml_declaration=True)