Python提供了多种方式来操作XML文件,使得XML文件的读取、写入、解析和修改变得非常简单和高效。通过使用Python的内置模块(例如xml.etree.ElementTree),我们可以轻松地读取XML文件并访问其中的元素、属性和文本内容。同时,Python也支持将数据转换为XML格式,并将其写入文件或传输到其他系统。
我们先一步一步解释代码:
未完全封装
一、打印XML文件的所有内容.
import xml.etree.ElementTree as ET
def print_xml_content(file_path):
"""
打印XML文件的所有内容.
参数:
- file_path (str): XML文件的路径.
"""
# 解析XML文件
tree = ET.parse(file_path)
# 获取根元素
root = tree.getroot()
# 递归打印元素内容
def recursive_print(element, indent=""):
# 打印当前元素的标签和属性
print(f"{indent}标签: {element.tag}, 属性: {element.attrib}")
# 打印当前元素的文本内容
if element.text:
print(f"{indent}文本: {element.text.strip()}")
# 递归打印子元素
for child in element:
recursive_print(child, indent + " ")
# 从根元素开始打印内容
recursive_print(root)
每行代码的意思:
import xml.etree.ElementTree as ET: 导入Python标准库xml.etree.ElementTree模块,将其重命名为ET以方便使用。
def print_xml_content(file_path):: 定义一个名为print_xml_content的函数,它接受一个参数file_path,表示XML文件的路径。
tree = ET.parse(file_path): 使用ET.parse()函数解析指定路径下的XML文件,并将解析结果存储在tree对象中。
root = tree.getroot(): 获取XML文件的根元素,并将其存储在root变量中。
def recursive_print(element, indent=""):: 定义一个名为recursive_print的内部函数,用于递归打印元素内容。它接受两个参数:element表示当前要打印的元素,indent表示当前要打印的内容的缩进。
print(f"{indent}标签: {element.tag}, 属性: {element.attrib}"): 打印当前元素的标签和属性信息,使用f-string进行格式化输出。
if element.text: print(f"{indent}文本: {element.text.strip()}"): 如果当前元素有文本内容,则打印当前元素的文本信息(去除多余空白字符)。
for child in element: recursive_print(child, indent + " "): 遍历当前元素的子元素,并使用递归方式调用recursive_print函数打印子元素的内容,缩进增加4个空格。
recursive_print(root): 从根元素开始打印XML文件的内容。
这个函数通过递归的方式遍历XML文件的元素,并打印出每个元素的标签、属性和文本内容。对于具有多层嵌套的XML结构,该函数可以清晰地展示每个元素的层次结构。
二、找到指定的XML元素并复制为新的一行,同时修改新行中的name属性的值
如图:
起始我的xml文件中name ='150831'
执行添加脚本后
注意脚本中的root.findall('program')中的program标签是根据实际改变
具体可看后面封装的脚本
def duplicate_element_with_custom_name(file_path, old_name, new_name):
"""
找到指定的XML元素并复制为新的一行,同时修改新行中的name属性的值.
参数:
- file_path (str): XML文件的路径.
- old_name (str): 要复制的元素中name属性的旧值.
- new_name (str): 新行中name属性的新值.
返回:
- bool: 添加成功返回True,否则返回False.
"""
try:
# 解析XML文件
tree = ET.parse(file_path)
root = tree.getroot()
# 找到指定的元素并复制为新的一行
for element in root.findall('program'):
if element.get('name') == old_name:
# 创建新的元素并复制属性
new_element = ET.Element('program')
for attr, value in element.items():
if attr == 'name':
value = new_name
new_element.set(attr, value)
# 添加到新的一行
root.append(new_element)
# 保存更改
tree.write(file_path)
return True
except Exception as e:
print("添加行时出错:", str(e))
return False
三、删除特定行的代码:
和上面的添加同理,找到指定的name属性 并删除特定的一行
import xml.etree.ElementTree as ET
def delete_element_by_name(file_path, name):
"""
根据指定的name属性的值删除XML文件中的元素行.
参数:
- file_path (str): XML文件的路径.
- name (str): 要删除的元素行的name属性的值.
返回:
- bool: 删除成功返回True,否则返回False.
"""
try:
# 解析XML文件
tree = ET.parse(file_path)
root = tree.getroot()
# 找到指定的元素并删除
for element in root.findall('program'):
if element.get('name') == name:
root.remove(element)
# 保存更改
tree.write(file_path)
return True
except Exception as e:
print("删除行时出错:", str(e))
return False
四、替换特定行中node属性的值的示例代码
如图替换node的值,实际情况可能是其他的值,此为变量,随实际改动
执行后
import xml.etree.ElementTree as ET
def replace_id_by_name(file_path, name, new_id):
"""
根据指定的name属性的值替换XML文件中元素行的id属性值.
参数:
- file_path (str): XML文件的路径.
- name (str): 要替换id属性值的元素行的name属性的值.
- new_id (str): 新的id属性值.
返回:
- bool: 替换成功返回True,否则返回False.
"""
try:
# 解析XML文件
tree = ET.parse(file_path)
root = tree.getroot()
# 找到指定的元素并替换id属性值
for element in root.findall('program'):
if element.get('name') == name:
element.set('id', new_id)
# 保存更改
tree.write(file_path)
return True
except Exception as e:
print("替换id时出错:", str(e))
return False
完全封装脚本
XML文件的读取、写入、解析和修改变得非常简单和高效
import xml.etree.ElementTree as ET
class XMLHandler:
def __init__(self, filepath):
self.filepath = filepath # XML文件路径
self.tree = ET.ElementTree() # 创建空的ElementTree对象
self.root = None # XML文件的根元素
def load_xml(self): # 加载XML文件
"""
加载XML文件并解析为ElementTree对象。
"""
try:
self.tree = ET.parse(self.filepath) # 解析XML文件为ElementTree对象
self.root = self.tree.getroot() # 获取XML文件的根元素
except ET.ParseError:
print("XML文件解析失败!")
def print_xml_content(self):
self.load_xml()
def recursive_print(element,indent=""):
print(f"{indent} 标签:{element.tag}, 属性:{element.attrib}") #打印当前元素的标签和属性
if element.text: #打印当前元素的文本内容
print(f"{indent} 文本:{element.text.strip()}")
for child in element: #打印子元素
recursive_print(child,indent + ' ')
recursive_print(self.root) #从根元素开始打印所有内容
def save_xml(self, output_filepath):
"""
将修改后的XML内容保存到指定的文件路径下。
参数:
- output_filepath: 输出的文件路径
"""
try:
self.tree.write(output_filepath, encoding="utf-8", xml_declaration=True) # 将修改后的内容写入文件
print("XML文件保存成功!")
except IOError:
print("XML文件保存失败!")
def find_elements(self, xpath):
"""
根据XPath表达式查找XML中的元素,并返回匹配的所有元素列表。
参数:
- xpath: XPath表达式
返回值:
- elements: 匹配的元素列表
"""
self.load_xml() #加载xml文件
elements = self.root.findall(xpath) # 使用findall方法查找匹配的元素
if elements:
return elements
else:
print("未找到匹配的元素!")
return []
def display_element(self,xpath):
"""
显示匹配xpath表达式的元素所有内容
:param xpath:
:return:
"""
elements = self.find_elements(xpath)
if elements:
for element in elements:
element_str = ET.tostring(element,encoding="utf-8").decode("utf-8")
print(element_str)
else:
print("未找到匹配的元素!")
def display_element_with_attribute(self,attribute,value):
"""
显示某一行指定的属性内容
:param attribute: 属性
:param value: 属性值
:return:
"""
self.load_xml()
target_node = None
for node in self.root.iter():
if attribute in node.attrib and node.attrib['name'] == value:
target_node = node
break
if target_node is not None:
print(target_node.attrib)
else:
print('未找到匹配的节点')
def add_element_with_attribute(self,attribute,value,add_attribute,add_value):
self.load_xml()
target_node = None
for node in self.root.iter():
if attribute in node.attrib and node.attrib['name'] == value:
target_node = node
break
if target_node is not None:
"""在某特定一行标签中添加所需内容"""
target_node.set(add_attribute,add_value)
print("属性已添加")
else:
print('未找到匹配的节点')
self.save_xml(output_filepath=self.filepath)
def add_element_with_custom_name(self,tag_name,old_name,new_name):
self.load_xml()
for element in self.root.findall(tag_name):
if element.get('name') == old_name:
new_element = ET.Element(tag_name)
for attr, value in element.items():
if attr == 'name':
value = new_name
new_element.set(attr, value)
self.root.append(new_element)
self.save_xml(output_filepath=self.filepath)
def remove_attribute_from_xml(self, attribute_name):
self.load_xml()
"""
参数:
- attribute_name(str): 要删除的内容的属性名称
"""
for element in self.root.iter(): #遍历xml文件中的所有元素
if attribute_name in element.attrib: #删除指定的属性内容
del element.attrib[attribute_name]
self.save_xml(output_filepath=self.filepath)
def remove_element_by_name(self,tag_name,name):
self.load_xml()
for element in self.root.findall(tag_name):
if element.get('name') == name:
self.root.remove(element)
self.save_xml(output_filepath=self.filepath)
def replace_element_by_name(self,name,value,new_value):
self.load_xml()
for element in self.root.findall(tag_name):
if element.get('name') == name:
element.set(value,new_value)
self.save_xml(output_filepath=self.filepath)
if __name__ == '__main__':
pass