Python 之 xml.etree.ElementTree 解析 xml 模块

Part.I Introduction

参考:
[1] python 标准库之xml.etree.ElementTree:https://zhuanlan.zhihu.com/p/152207687
[2] 官网:https://docs.python.org/3/library/xml.etree.elementtree.html
[3] 使用ElementTree处理XML缩进和换行:https://blog.csdn.net/u012692537/article/details/101395192
[4] Python创建、修改、保存XML文件:https://blog.csdn.net/weixin_42782150/article/details/106219001

ElementTreepythonXML处理模块,它提供了一个轻量级的对象模型。它在Python2.5以后成为Python标准库的一部分,但是Python2.4之前需要单独安装。在使用ElementTree模块时,一般可以进行如下的import

import xml.etree.ElementTree as ET

ElementTree表示整个XML节点树,而Element表示节点数中的一个单独的节点。每个Element对象都具有以下属性:

  • tag: string 对象,表示数据代表的种类;
  • attrib: dictionary 对象,表示附有的属性;
  • text: string对象,表示 element 的内容;
  • tail: string对象,表示element闭合之后的尾迹;
  • ele[i]: child elements,若干子元素,一个Element对象可以看成是一个list,可以for循环,可以用索引。

Part.II 基础知识

下面是一些常用的函数操作:

名称示例含义
ET.parse(fname)tree = ET.parse(f1)将文件f1中的数据载入到tree中,返回类型是xml.etree.ElementTree.ElementTree
tree.getroot()root = tree.getroot()获取树的根节点,返回类型是xml.etree.ElementTree.Element
Element.set('AttributeName','AttributeValue')root[0].set('name','9999')将元素某个属性的值设置为'AttributeValue',如果属性'AttributeName'不存在,就新建一个属性
ET.Element(tagname)nd = ET.Element('root')新建一个元素,将其tag设置为root,如果想设置它的text,可以直接使用root.text=value
Element.append(childElement)新增子节点
Element.remove(childElement)删除子节点
ET.ElementTree(Element)tree = ET.ElementTree(root)将节点Element作为根节点,新建一个树
tree.write(fname)tree.write(f2)将一个树写到文件中

获取元素的一些属性或值

  • nd.tag: 获取节点的名字,返回是一个字符串(可读可写)
  • nd.attrib: 获取节点的属性,返回一个字典型数据{属性名: 属性值}
  • nd.text: 获取节点的内容(值)

下面给出一个示例,具体说明上面的属性的含义

<movie title="Enemy Behind"> mv_value
   <type name="9999">War, Thriller</type>
</movie>  

如果上面的存到一个文件中进行读取,那么roottag(名字)就是movie,它有个属性title其值为Enemy Behind,另外它的textmv_value;它的子节点root[0]是以typetag的一个元素。

Part.III 轮子

因为比较简单,一看就可以上手,并且引用文章也有很多实操笔记,所以这里就不详细介绍实际操作的过程了,下面是根据一些需求所写的小函数,需要的自取。

Chap.I 用缩进和换行增加可读性

摘自
使用ElementTree处理XML缩进和换行:https://blog.csdn.net/u012692537/article/details/101395192

def pretty_xml(element, indent, newline, level=0):  # elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行
    """ 
    Beautify the xml-file.
    @author:    CSDN - u012692537
    @date:      2019-09-25
    > @param[in] element:           The root element
    > @param[in] indent:            The indent symbol
    > @param[in] newline:           The newline symbol
    > @param[in] level:             The number of indent symbol, 0 is 1.
    return: 
    < @param[out] void
    """
    if element:  # Judge Dose sub-element exist?
        if (element.text is None) or element.text.isspace():  # If the ele.text is null
            element.text = newline + indent * (level + 1)
        else:
            element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
            # else:  # 此处两行如果把注释去掉,Element的text也会另起一行
            # element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * level
    temp = list(element)  # Convert element to list
    for subelement in temp:
        # # 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致
        if temp.index(subelement) < (len(temp) - 1):
            subelement.tail = newline + indent * (level + 1)
        else:  # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个
            subelement.tail = newline + indent * level
        pretty_xml(subelement, indent, newline, level=level + 1)  # 对子元素进行递归操作

另外,如果有多个attrib,想让每个attrib独占一行该如何操作呢?

Chap.II attrib 和 subElement 之间的相互转化

def process_G2_to_G1(f1,f2):
    """ 
    Convert subElement to attribute.
    > @param[in] f1:                The raw xml-file
    > @param[in] f2:                The new xml-file
    return: 
    < @param[out] void
    """
    tree = ET.parse(f1)
    root = tree.getroot()
    root_new=ET.Element(root.tag)
    root_new.text=""
    for ele in root:
        tag=ele.tag
        text=ele.text
        root_new.set(tag,text)
    pretty_xml(root_new, '\t', '\n')  # 执行美化方法
    tree_new=ET.ElementTree(root_new)
    tree_new.write(f2)
    return 0

def process_G1_to_G2(f1,f2):
    """ 
    Convert attribute to subElement.
    > @param[in] f1:                The raw xml-file
    > @param[in] f2:                The new xml-file
    return: 
    < @param[out] void
    """
    tree = ET.parse(f1)
    root = tree.getroot()
    root_new=ET.Element(root.tag)
    for key, val in root.attrib.items():
        ele=ET.Element(key)
        ele.text=val
        root_new.append(ele)
    pretty_xml(root_new, '\t', '\n')  # 执行美化方法
    tree_new=ET.ElementTree(root_new)
    tree_new.write(f2)
    return 0

但是还存在一个问题:转换之后的子节点或属性会按字母序排列,和原来的顺序不能保持一致,为了解决这个问题可以尝试https://blog.csdn.net/weixin_44800045/article/details/118379794

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流浪猪头拯救地球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值