文章目录
- Part.I Introduction
- Part.II 基础知识
- Part.III 轮子
- Chap.I 用缩进和换行增加可读性
- Chap.II attrib 和 subElement 之间的相互转化
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缩进和换行: [4] Python创建、修改、保存XML文件:
ElementTree
是python
的XML
处理模块,它提供了一个轻量级的对象模型。它在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 基础知识
下面是一些常用的函数操作:
名称 | 示例 | 含义 |
|
| 将文件 |
|
| 获取树的根节点,返回类型是 |
|
| 将元素某个属性的值设置为 |
|
| 新建一个元素,将其 |
| 新增子节点 | |
| 删除子节点 | |
|
| 将节点 |
|
| 将一个树写到文件中 |
获取元素的一些属性或值
-
nd.tag
: 获取节点的名字,返回是一个字符串(可读可写) -
nd.attrib
: 获取节点的属性,返回一个字典型数据{属性名: 属性值}
-
nd.text
: 获取节点的内容(值)
下面给出一个示例,具体说明上面的属性的含义
<movie title="Enemy Behind"> mv_value
<type name="9999">War, Thriller</type>
</movie>
如果上面的存到一个文件中进行读取,那么root
的tag
(名字)就是movie
,它有个属性title
其值为Enemy Behind
,另外它的text
是mv_value
;它的子节点root[0]
是以type
为tag
的一个元素。
Part.III 轮子
因为比较简单,一看就可以上手,并且引用文章也有很多实操笔记,所以这里就不详细介绍实际操作的过程了,下面是根据一些需求所写的小函数,需要的自取。
Chap.I 用缩进和换行增加可读性
摘自
使用ElementTree处理XML缩进和换行:
def pretty_xml(element, indent, newline, level=0): # elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行
"""
> @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
但是还存在一个问题:转换之后的子节点或属性会按字母序排列,和原来的顺序不能保持一致,为了解决这个问题可以尝试