Python使用ElementTree美化XML格式的操作


Posted in Python onMarch 06, 2020

Python中使用ElementTree可以很方便的处理XML,但是产生的XML文件内容会合并在一行,难以看清楚。

如下格式:

<root><aa>aatext<cc>cctext</cc></aa><bb>bbtext<dd>ddtext<ee>eetext</ee></dd></bb></root>

使用minidom模块中的toprettyxml和writexml方法都有参数可以优化XML,但是有两个问题:

a. 如果解析的XML已经是美化过的,那么执行该方法会多出很多空行

b. 产生的结果会将text也独立一行,如下:

<root> 
  <aa> 
    aatext 
  </aa> 
  <bb> 
    bbtext 
  </bb> 
</root>

而我想产生如下结果:

<root> 
  <aa>aatext</aa> 
  <bb>bbtext</bb> 
</root>

于是只能自己写一个美化XML的方法。

我们首先研究一下ElementTree模块中的Element类,使用getroot方法返回的便是Element类。

该类中有四个属性tag、attrib、text与tail, 对应在XML中如下图所示:

Python使用ElementTree美化XML格式的操作

整个XML就是一个Element,里面嵌套了很多子Element。

Element可以使用for循环迭代。

通过在text和tail中增加换行和制表符,就可以实现美化XML的目的。

美化代码如下:

def prettyXml(element, indent, newline, level = 0): # elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行 
  if element: # 判断element是否有子元素 
    if element.text == None or element.text.isspace(): # 如果element的text没有内容 
      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) # 将elemnt转成list 
  for subelement in temp: 
    if temp.index(subelement) < (len(temp) - 1): # 如果不是list的最后一个元素,说明下一个行是同级别元素的起始,缩进应一致 
      subelement.tail = newline + indent * (level + 1) 
    else: # 如果是list的最后一个元素, 说明下一行是母元素的结束,缩进应该少一个 
      subelement.tail = newline + indent * level 
    prettyXml(subelement, indent, newline, level = level + 1) # 对子元素进行递归操作 
     
from xml.etree import ElementTree   #导入ElementTree模块 
tree = ElementTree.parse('test.xml')  #解析test.xml这个文件,该文件内容如上文 
root = tree.getroot()         #得到根元素,Element类 
prettyXml(root, '\t', '\n')      #执行美化方法 
ElementTree.dump(root)         #显示出美化后的XML内容

输出结果如下:

<root> 
  <aa> 
    aatext 
    <cc>cctext</cc> 
  </aa> 
  <bb> 
    bbtext 
    <dd> 
      ddtext 
      <ee>eetext</ee> 
    </dd> 
  </bb> 
</root>

残留问题点:

windows下的换行符是"\r\n",只需将prettyXml方法的第三个参数改为"\r\n",使用记事本打开生成的XML大部分OK。

但是XML说明与根元素开始符之间不知如何插入"\r\n".

Python使用ElementTree美化XML格式的操作

补充知识:python-xml 模块-代码生成xml 文档

一、XML 模块

什么是xml:可扩展的标记语言,标记翻译为标签,用标签来组织数据的语言,也是一种语言可以用来自定义文档结构。相比json 使用场景更加广泛,但是语法格式相比json 复杂很多

什么时候使用json:前后台交互数据时使用json

什么时候使用xml:当需要自定义文档结构时使用xml,比如java中经常用xml来作为配置文件,常见操作就是通过程序去读取配置信息,而修改增加删除,一般是交给用户来手动完成

标签的叫发:node(节点)、elment(元素)、tag(标签)

需求从conuntrys中获取所有的国家名称

==========================>countrys
<data>
  <country name="Liechtenstein">
    <rank updated="yes">2</rank>
    <year>2009</year>
    <gdppc>141100</gdppc>
    <neighbor direction="E" name="Austria" />
    <neighbor direction="W" name="Switzerland" />
  </country>
  <country name="Singapore">
    <rank updated="yes">5</rank>
    <year>2012</year>
    <gdppc>59900</gdppc>
    <neighbor direction="N" name="Malaysia" />
  </country>
  <country name="Panama">
    <rank updated="yes">69</rank>
    <year>2012</year>
    <gdppc>13600</gdppc>
    <neighbor direction="W" name="Costa Rica" />
    <neighbor direction="E" name="Colombia" />
  </country>
</data># 取别名可以用于简化书写
import xml.etree.ElementTree as ET
tree = ET.parse('countrys')
#获取根标签#第一种获取标签的方式
#全文查找
iter() 
# 获取迭代器 如果不指定参数 则迭代器迭代的是所有标签
print(root.iter())
# 获取迭代器 如果指定参数 则迭代器迭代的是所有名称匹配的标签
for e in root.iter("rank"):
  print(e)
 
#第二种获取标签的方式
#在当前标签下(所有子级标签)寻找第一个名称匹配的标签
print(root.find("rank")) #第一个名称不匹配所以返回None#第三种获取标签的方式
#在当前标签下(所有子级标签)寻找所有名称匹配的标签
print(root.findall("rank")) #[]

练习:找到新加坡中year 这个标签

#print(e.tag) #标签名称
#print(e.attrib) #属性 字典类型
#print(e.text) #文本内容import xml.etree.ElementTree as ETtree = ET.parse("countrys")
# 获取根标签
root = tree.getroot()
for e in root.iter("country"):
  if e.attrib["name"] == "Singapore":
    y = e.find("year")
    print(y.text) #2012

在程序中修改文档内容:把所有year标签的文本加1

import xml.etree.ElementTree as ETtree = ET.parse("countrys")
root = tree.getroot()
for e in root.iter("year"):
  e.text = str(int(e.text) + 1)
  
#做完修改后要将修改后的内容写入文件
tree.write('countrys')

把新加坡国家删除:

import xml.etree.ElementTree as ETtree = ET.parse("countrys")
root = tree.getroot()for e in root.findall("country"):
  print(e)
  if e.attrib["name"] == "Singapore":
    #删除时要通过被删除的父级标签来删除
    root.remove(e)tree.write('countrys')

用程序将中国信息写入文档中:

import xml.etree.ElementTree as ETtree = ET.parse("countrys")
root = tree.getroot()
#添加时也需要将要添加的数据做成一个Element
c = ET.Element("country",{"name":"china"})# 在国家下有一堆子标签
ranke = ET.Element("ranke",{"updated":"yes"})
c.append(ranke)year = ET.Element("year")
year.text = "2018"
c.append(year)#添加到root标签中
root.append(c)
tree.write("countrys")

总结:一般不会通过程序 去修改 删除 和添加

什么时候应该使用XML格式:

当你需要自定文档结构时(XML最强大的地方就是结构)

前后台交互不应该使用,前后台交互应该使用JSON格式

代码生成XML文档

import xml.etree.ElementTree as ET# 创建根标签
root = ET.Element("root")
root.text = "这是一个XML文档!"c = ET.Element("country",{"name":"china"})
root.append(c)tree = ET.ElementTree(root)
# 参数: 文件名称 编码方式 是否需要文档声明
tree.write("new.xml",encoding="utf-8",xml_declaration=True)=========================>new.xml 内容为
<?xml version='1.0' encoding='utf-8'?>
<root>这是一个XML文档!<country name="china" /></root>

以上这篇Python使用ElementTree美化XML格式的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用ftplib实现简易FTP客户端的方法
Jun 03 Python
简单讲解Python中的数字类型及基本的数学计算
Mar 11 Python
Python分析学校四六级过关情况
Nov 22 Python
Python实现pdf文档转txt的方法示例
Jan 19 Python
python xlsxwriter库生成图表的应用示例
Mar 16 Python
python操作小程序云数据库实现简单的增删改查功能
Jun 06 Python
windows上安装python3教程以及环境变量配置详解
Jul 18 Python
Python高级编程之消息队列(Queue)与进程池(Pool)实例详解
Nov 01 Python
Pytorch实现LSTM和GRU示例
Jan 14 Python
解决tensorflow打印tensor有省略号的问题
Feb 04 Python
Python操作Excel工作簿的示例代码(\*.xlsx)
Mar 23 Python
Python xlrd/xlwt 创建excel文件及常用操作
Sep 24 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
Mar 06 #Python
Python 批量读取文件中指定字符的实现
Mar 06 #Python
python GUI库图形界面开发之PyQt5布局控件QGridLayout详细使用方法与实例
Mar 06 #Python
python3 xpath和requests应用详解
Mar 06 #Python
python 装饰器功能与用法案例详解
Mar 06 #Python
python GUI库图形界面开发之PyQt5布局控件QVBoxLayout详细使用方法与实例
Mar 06 #Python
利用 Python ElementTree 生成 xml的实例
Mar 06 #Python
You might like
最小化数据传输――在客户端存储数据
2006/10/09 PHP
WordPress中登陆后关闭登陆页面及设置用户不可见栏目
2015/12/31 PHP
详解js异步文件加载器
2016/01/24 PHP
Yii框架结合sphinx,Ajax实现搜索分页功能示例
2016/10/18 PHP
PHP7 foreach() 函数修改
2021/03/09 PHP
修改jquery.lazyload.js实现页面延迟载入
2010/12/22 Javascript
jquery中event对象属性与方法小结
2013/12/18 Javascript
实例分析js和C#中使用正则表达式匹配a标签
2014/11/26 Javascript
node.js中的fs.utimesSync方法使用说明
2014/12/15 Javascript
JavaScript中的null和undefined区别介绍
2015/01/01 Javascript
实现音乐播放器的代码(html5+css3+jquery)
2015/08/04 Javascript
jQuery实现下滑菜单导航效果代码
2015/08/25 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
2015/08/27 Javascript
javascript实现label标签跳出循环操作
2016/03/06 Javascript
jQuery实现无限往下滚动效果代码
2016/04/16 Javascript
BootStrap Table 分页后重新搜索问题的解决办法
2016/08/08 Javascript
javascript表单正则应用
2017/02/04 Javascript
vue.js删除动态绑定的radio的指定项
2017/06/02 Javascript
angularJs自定义过滤器实现手机号信息隐藏的方法
2018/10/08 Javascript
微信小程序导航栏跟随滑动效果的实现代码
2019/05/14 Javascript
vuex + keep-alive实现tab标签页面缓存功能
2019/10/17 Javascript
python文件读写并使用mysql批量插入示例分享(python操作mysql)
2014/02/17 Python
浅析Python中的序列化存储的方法
2015/04/28 Python
Python 3中print函数的使用方法总结
2017/08/08 Python
python调用c++ ctype list传数组或者返回数组的方法
2019/02/13 Python
Django框架中间件定义与使用方法案例分析
2019/11/28 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
2020/02/04 Python
完美解决pycharm 不显示代码提示问题
2020/06/02 Python
python小白学习包管理器pip安装
2020/06/09 Python
Python Scrapy图片爬取原理及代码实例
2020/06/12 Python
Pandas之缺失数据的实现
2021/01/06 Python
医院标语大全
2014/06/23 职场文书
税务干部群众路线教育实践活动自我剖析材料
2014/09/21 职场文书
小学教师先进事迹材料
2014/12/15 职场文书
Go 自定义package包设置与导入操作
2021/05/06 Golang
Redis入门教程详解
2021/08/30 Redis