【2】文件读写-2-9-python读写xml

一、创建xml

xml.dom.minidom模块实现创建一个XML文档。

创建XML的过程:

  1. 内存数据产生
  2. 产生xml内存对象(也就是DOM树)
  3. 产生根对象
  4. 往根对象里加数据
  5. 把xml内存对象写到文件

下面是一个创建xml文档的简单实例:

import xml.dom.minidom

#在内存中创建一个空的文档
doc = xml.dom.minidom.Document() 

#创建一个根节点Managers对象
root = doc.createElement('Managers') 

#设置根节点的属性
root.setAttribute('company', 'xx科技') 
root.setAttribute('address', '科技软件园') 
#将根节点添加到文档对象中
doc.appendChild(root) 

managerList = [{'name' : 'joy',  'age' : 27, 'sex' : '女'},
							{'name' : 'tom', 'age' : 30, 'sex' : '男'},
							{'name' : 'ruby', 'age' : 29, 'sex' : '女'}
]

for i in managerList :
	nodeManager = doc.createElement('Manager')
	nodeName = doc.createElement('name')
	#给叶子节点name设置一个文本节点,用于显示文本内容
	nodeName.appendChild(doc.createTextNode(str(i['name'])))

	nodeAge = doc.createElement("age")
	nodeAge.appendChild(doc.createTextNode(str(i["age"])))

	nodeSex = doc.createElement("sex")
	nodeSex.appendChild(doc.createTextNode(str(i["sex"])))

	#将各叶子节点添加到父节点Manager中,
	#最后将Manager添加到根节点Managers中
	nodeManager.appendChild(nodeName)
	nodeManager.appendChild(nodeAge)
	nodeManager.appendChild(nodeSex)
	root.appendChild(nodeManager)
#开始写xml文档
fp = open('c:\\wcx\\Manager.xml', 'w')
doc.writexml(fp, indent='\t', addindent='\t', newl='\n', encoding="utf-8")

执行结果: 

<?xml version="1.0" encoding="utf-8"?>
		<Managers address="科技软件园" company="xx科技">
				<Manager>
						<name>joy</name>
						<age>27</age>
						<sex>女</sex>
				</Manager>
				<Manager>
						<name>tom</name>
						<age>30</age>
						<sex>男</sex>
				</Manager>
				<Manager>
						<name>ruby</name>
						<age>29</age>
						<sex>女</sex>
				</Manager>
		</Managers>

参数解析:

writexml(writer, indent, addindent, newl, encoding)

writer是文件对象
indent是每个tag前填充的字符,如:'  ',则表示每个tag前有两个空格
addindent是每个子结点的缩近字符,如下面的例子中单引号中我直接用的tab键
newl是每个tag后填充的字符,如:'\n',则表示每个tag后面有一个回车
encoding是生成的XML信息头中的encoding属性值,在输出时minidom并不真正进行编码的处理,如果你保存的文本内容中有汉字,则需要自已进行编码转换。

二、读xml

xml文件示例:

<?xml version="1.0" encoding="utf-8" ?>
<!-- This is list of customers -->
<customers>
	<customer ID="C001">
		<name>Acme Inc.</name>
		<phone>12345</phone>
		<comments>
			<![CDATA[Regular customer since 1995]]>
		</comments>
	</customer>
	<customer ID="C002">
		<name>Star Wars Inc.</name>
		<phone>23456</phone>
		<comments>
			<![CDATA[A small but healthy company.]]>
		</comments>
	</customer>
</customers>

读的代码:

# -*- coding: utf-8 -*-
"""
		@Author  : LiuZhian
		@Time    : 2019/4/24 0024 上午 9:19
		@Comment : 
"""
from xml.dom.minidom import parse
def readXML():
	domTree = parse("./customer.xml")
	# 文档根元素
	rootNode = domTree.documentElement
	print(rootNode.nodeName)

	# 所有顾客
	customers = rootNode.getElementsByTagName("customer")
	print("****所有顾客信息****")
	for customer in customers:
		if customer.hasAttribute("ID"):
			print("ID:", customer.getAttribute("ID"))
			# name 元素
			name = customer.getElementsByTagName("name")[0]
			print(name.nodeName, ":", name.childNodes[0].data)
			# phone 元素
			phone = customer.getElementsByTagName("phone")[0]
			print(phone.nodeName, ":", phone.childNodes[0].data)
			# comments 元素
			comments = customer.getElementsByTagName("comments")[0]
			print(comments.nodeName, ":", comments.childNodes[0].data)

if __name__ == '__main__':
	readXML()

输出示例:

。。。

三、替换内容

def updateXML():
	domTree = parse("./customer.xml")
	# 文档根元素
	rootNode = domTree.documentElement

	names = rootNode.getElementsByTagName("name")
	for name in names:
		if name.childNodes[0].data == "Acme Inc.":
			# 获取到name节点的父节点
			pn = name.parentNode
			# 父节点的phone节点,其实也就是name的兄弟节点
			# 可能有sibNode方法,我没试过,大家可以google一下
			phone = pn.getElementsByTagName("phone")[0]
			# 更新phone的取值
			phone.childNodes[0].data = 99999

	with open('updated_customer.xml', 'w') as f:
		# 缩进 - 换行 - 编码
		domTree.writexml(f, addindent='  ', encoding='utf-8')

if __name__ == '__main__':
	updateXML()

四、我的内容

4.1 将xml文件拆分成多个文件

domTree = xml.dom.minidom.parse(INPUT)
# 文档根元素
rootNode = domTree.documentElement
customers = rootNode.getElementsByTagName("Sequence")
fpobj_list = []
fpobj_list_raw = []

new_doc = xml.dom.minidom.Document() 
new_root = new_doc.createElement('PredictionResults') 
new_doc.appendChild(new_root) 
num = 0
xml_id = 0
# print(len(customers))

for child in customers:
		num+=1
		new_root.appendChild(child)
		if num >=cut_num :
				num = 0
				xml_id +=1
				# xml_fp = 
				fp = open('%s/tmp-%s.xml'%(resultdir,xml_id), 'w')
				new_doc.writexml(fp, encoding="utf-8") 

				new_doc = xml.dom.minidom.Document() 
				new_root = new_doc.createElement('PredictionResults') 
				new_doc.appendChild(new_root) 
				
		if num == len(customers):
				xml_id +=1
				fp = open('%s/tmp-%s.xml'%(resultdir,xml_id), 'w')
				new_doc.writexml(fp, encoding="utf-8") 

参考资料

个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn