首先需要导入相应的库:
使用基于ELementTree时:import xml.etree.ElementTree as ET
使用基于DOM时: import xml.dom.minidom as minidom
基于ElementTree写入XML
- 创建节点 :root = ET.Element(‘Root’)
- 创建文档 :tree = ET.ElementTree(root)
- 设置文本值:element.text = ‘default’
- 设置属性:element.set(‘age’, str(i))
- 添加节点:root.append(element)
- 写入文档:tree.write(‘default.xml’, encoding=‘utf-8’, xml_declaration=True)
但这样写入会有个问题,写入的XML会在同一行,缺少换行符,Etree本身并没有提供换行的选项,翻看了国外大神的回答,对root处理以后,再次写入将有换行符。完整代码如下:
# -*- coding:utf-8 -*-
import xml.etree.ElementTree as ET
# 增加换行符
def __indent(elem, level=0):
i = "\n" + level*"\t"
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + "\t"
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
__indent(elem, level+1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
root = ET.Element('Root') # 创建节点
tree = ET.ElementTree(root) # 创建文档
for i in range(5):
element = ET.Element('Name')
element.set('age', str(i))
element.text = 'default'
root.append(element)
__indent(root) # 增加换行符
tree.write('default.xml', encoding='utf-8', xml_declaration=True)
文档内容
<?xml version='1.0' encoding='utf-8'?>
<Root>
<Name age="0">default</Name>
<Name age="1">default</Name>
<Name age="2">default</Name>
<Name age="3">default</Name>
<Name age="4">default</Name>
</Root>
基于ElementTree读取XML
- 读取文档:tree = ET.parse(‘default.xml’)
- 获得根节点:root = tree.getroot()
- 获得所有子节点:list(root)
- 查找子节点,不会递归查找所有子节点:root.findall(‘Name’)
- 查找子节点,递归查找所有子节点:root.iter(‘Name’)
- 查看节点名称:root.tag
示例代码:
# -*- coding:utf-8 -*-
import xml.etree.ElementTree as ET
tree = ET.parse('default.xml')
root = tree.getroot()
for node in list(root):
print(node.text, node.tag, node.get('age'))
for node in root.findall('Name'):
print(node.text, node.tag, node.get('age'))
输出
default Name 0
default Name 1
default Name 2
default Name 3
default Name 4
default Name 0
default Name 1
default Name 2
default Name 3
default Name 4
基于DOM写入XML
- 创建文档: dom = minidom.getDOMImplementation().createDocument(None,‘Root’,None)
- 获得根节点:root = dom.documentElement
- 创建节点:element = dom.createElement(‘Name’)
- 给这个节点添加文本:element.appendChild(dom.createTextNode(‘default’)) 注意:这里的节点文本值是存成另外一个节点的,是createTextNode
- 设置属性:element.setAttribute(‘age’, ‘20’)
- 添加到节点:root.appendChild(element)
代码示例:
#-*- coding:utf-8 -*-
import xml.dom.minidom as minidom
dom = minidom.getDOMImplementation().createDocument(None,'Root',None)
root = dom.documentElement
for i in range(5):
element = dom.createElement('Name')
element.appendChild(dom.createTextNode('default'))
element.setAttribute('age', str(i))
root.appendChild(element)
#保存文件
with open('default.xml', 'w', encoding='utf-8') as f:
dom.writexml(f, addindent='\t', newl='\n',encoding='utf-8')
文档内容
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Name age="0">default</Name>
<Name age="1">default</Name>
<Name age="2">default</Name>
<Name age="3">default</Name>
<Name age="4">default</Name>
</Root>
基于DOM读取XML
- 读取文档:dom = minidom.parse(‘default.xml’)
- 获得根节点:root = dom.documentElement
- 按照名称查找子节点,注意这里会递归查找所有子节点:names = root.getElementsByTagName(‘Name’)
- 所有的子节点:root.childNodes
注意:每个节点的文本值存在TextNode节点中,也就是最后一个节点的第一个子节点 - 查看是否含有属性:name.hasAttribute(‘age’) 查看属性:name.getAttribute(‘age’)
示例代码:
dom = minidom.parse('default.xml')
root = dom.documentElement
names = root.getElementsByTagName('Name')
for name in names:
# 它的第一个子节点是一个textnode,存取的是真正的节点值
print(name.childNodes[0].nodeValue, end='\t')
if name.hasAttribute('age'):
print(name.getAttribute('age'), end='\t')
print('')
输出
default 0
default 1
default 2
default 3
default 4 ```