Python 有三种方法解析 XML。SAX,DOM,以及 ElementTree:
1.SAX (simple API for XML )
Python 标准库包含 SAX 解析器,SAX 用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。
2.DOM(Document Object Model)
将 XML 数据在内存中解析成一个树,通过对树的操作来操作XML。
3.ElementTree(元素树)
ElementTree就像一个轻量级的DOM,具有方便友好的API。代码可用性好,速度快,消耗内存少。
注:因DOM需要将XML数据映射到内存中的树,一是比较慢,二是比较耗内存,而SAX流式读取XML文件,比较快,占用内存少,但需要用户实现回调函数(handler)。
xml.etree.ElementTree模块实现了一个简单高效的API,用于解析和创建XML数据。
警告 该xml.etree.ElementTree模块对于恶意构建的数据是不安全的。如果您需要解析不可信或未经身份验证的数据,请参见XML漏洞。
ElementTree对xml操作分为两级。
xml.etree.ElementTree.ElementTree(element=None, file=None)
。对于xml整个文件的操作(读、写等)是在这一级上。class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
。对于xml元素的操作则在这一级上。这个是看菜鸟教程用的xml,这里去掉了几个换行
<collection shelf="New Arrivals">
<movie title="Enemy Behind"><type>War, Thrillertype><format>DVDformat>
<year>2003year>
<rating>PGrating>
<stars>10stars>
<description>Talk about a US-Japan wardescription>
movie><movie title="Transformers">
<type>Anime, Science Fictiontype>
<format>DVDformat>
<year>1989year>
<rating>Rrating>
<stars>8stars>
<description>A schientific fictiondescription>
movie><movie title="Trigun">
<type>Anime, Actiontype>
<format>DVDformat>
<episodes>4episodes>
<rating>PGrating>
<stars>10stars>
<description>Vash the Stampede!description>
movie>
<movie title="Ishtar">
<type>Comedytype>
<format>VHSformat>
<rating>PGrating>
<stars>2stars>
<description>Viewable boredomdescription>
movie>
collection>
import xml.etree.ElementTree as ET
# 从文件读
tree = ET.parse('movies.xml')
root = tree.getroot()
# 从字符串读
# root = ET.fromstring(country_data_as_string)
root 是 Element 类,有标签和属性字典root.tag,root.attrib
这个是处理换行和缩进的代码
from xml.etree import ElementTree # 导入ElementTree模块
def pretty_xml(element, indent, newline, level=0): # elemnt为传进来的Elment类,参数indent用于缩进,newline用于换行
if element: # 判断element是否有子元素
if (element.text is 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) # 将element转成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
pretty_xml(subelement, indent, newline, level=level + 1) # 对子元素进行递归操作
tree = ElementTree.parse('movies.xml') # 解析movies.xml这个文件
root = tree.getroot() # 得到根元素,Element类
pretty_xml(root, '\t', '\n') # 执行美化方法
tree.write('output.xml')