专业编程基础技术教程

网站首页 > 基础教程 正文

Python轻松驾驭XML:实现高效的文件操作

ccvgpt 2024-08-05 12:18:47 基础教程 14 ℃

Python提供了多种方式来操作XML文件,使得XML文件的读取、写入、解析和修改变得非常简单和高效。通过使用Python的内置模块(例如xml.etree.ElementTree),我们可以轻松地读取XML文件并访问其中的元素、属性和文本内容。同时,Python也支持将数据转换为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

Tags:

最近发表
标签列表