给定一个 XML 文件,该文件包含许多 scen 节点,每个 scen 节点包含一个或多个 case 节点,每个 case 节点又包含一个 res 节点。目标是解析这个 XML 文件,并创建一个新的 XML 文件,其中具有相同名称的 case 节点被合并在一起,而 res 节点的内容被连接成一个字符串。
解决方案
- 从 XML 文件中提取
scen节点:
import xml.etree.ElementTree as ET
tree = ET.parse('input.xml')
root = tree.getroot()
scen_nodes = root.findall('.//scen')
- 提取
scen节点中相同名称的case节点:
from collections import defaultdict
# 使用字典来存储具有相同名称的 `case` 节点
index = defaultdict(list)
for scen_node in scen_nodes:
for case_node in scen_node.findall('./case'):
case_name = case_node.get('name')
index[case_name].append(case_node)
- 创建新的 XML 文件的根节点:
nRoot = ET.Element('root')
- 遍历字典中的键值对,并将具有相同名称的
case节点合并成一个新的case节点:
for case_name, case_nodes in index.items():
# 创建新的 `case` 节点
new_case_node = ET.Element('case', name=case_name)
# 将具有相同名称的 `res` 节点的内容连接成一个字符串
res_list = []
for case_node in case_nodes:
res_list.append(case_node.find('./res').text)
new_case_node.text = ', '.join(res_list)
# 将新的 `case` 节点添加到 `scen` 节点中
scen_node = case_nodes[0].getparent()
scen_node.append(new_case_node)
- 将合并后的
scen节点添加到新的 XML 文件的根节点中:
for scen_node in scen_nodes:
nRoot.append(scen_node)
- 将新的 XML 文件写入文件中:
tree = ET.ElementTree(nRoot)
tree.write('output.xml', encoding='utf-8', xml_declaration=True)
代码例子
# sample input.xml file
input_xml = '''
<root>
<scen name="n1">
<case name="c1">
<res>Text1</res>
</case>
</scen>
<scen name="n2">
<case name="c234">
<res>Text</res>
</case>
</scen>
<scen name="n1">
<case name="c2">
<res>Text1</res>
</case>
<case name="c1">
<res>Text2</res>
</case>
</scen>
</root>
'''
# parse input xml file
input_root = ET.fromstring(input_xml)
# merge case nodes with the same name
def merge_cases(root):
index = defaultdict(list)
for scenario in root.findall(".//scenario"):
index[scenario.get('name')].append(scenario.getchildren())
nRoot = ET.Element('root')
elems = []
for i in index:
scen = ET.Element('scenario',name=i)
for elem in index[i]:
for e in elem:
scen.append(e)
elems.append(scen)
nRoot.extend(elems)
return nRoot
# create new xml file with merged case nodes
output_root = merge_cases(input_root)
# write output xml file
output_xml = ET.tostring(output_root, encoding='utf-8', xml_declaration=True)
with open('output.xml', 'wb') as f:
f.write(output_xml)
print('XML file parsed and cases merged successfully!')
运行上面的代码,将在 output.xml 文件中生成新的 XML 文件,其中具有相同名称的 case 节点已经被合并,而 res 节点的内容被连接成一个字符串。