pythonxml.dom.minidom解析xml,创建,读取,添加
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#/dev/peps/pep-0263/
# @Data 2020/9/19 13:58
import os
from xml.dom.minidom import parse
from xml.dom.minidom import Document
from xml.dom.minidom import parseString
import tostring
# 参考:
python处理xml文件# # 1.www.pythonf/read/108626
# # 2.wwwblogs/zhouzhou0/p/10525821.html
# # 3.wwwblogs/boyeestudio/archive/2005/08/16/216408.html
# # 4.wwwblogs/itech/archive/2011/01/06/1924972.html
# # 5.blog.csdn/qq_37174526/article/details/89489212
# # 6.blog.csdn/lucy82910/article/details/80308118
# # 7.denong/cs105295539/
#本⽂的xml是参照同花顺“实时解盘.xml”
#⾸先这⾥先明确⼀下,xml⽂件其实就是根节点下⾯挂载了很多节点,节点下⾯⼜挂载了很多⼦节点,就这样像⼀棵树⼀样,
# 其实节点只要挂载顺序弄好了,就⾏,就是⼀层⼀层挂载
#如下图所⽰:
# 所⽣成的xml
# <?xml version="1.0" encoding="utf-8"?>
# <rootinfo>
# <infodata infoid="57344">
# <data>
# <status>1</status>
# <title>1111111</title>
# <time>1596678431</time>
# <properties>111111111111</properties>
# </data>
# <data>
# <status>9</status>
# <title>111111111111111111</title>
# <time>1596678436</time>
# <properties>11111111111111</properties>
# </data>
# </infodata>
# </rootinfo>
def createXml(xml_path):
#parse 解析⽂件或者⽂件对象,⽂件对象没操作,参照其官⽅⽂档,应该是句柄
#官⽅⽂档: /3/library/xml.dom.minidom.html
# dom1 = parse('c:\\temp\\l') # parse an XML file by name
#
# datasource = open('c:\\temp\\l') open打开后返回的是句柄
# dom2 = parse(datasource) # parse an open file
# 操作的内容如果是字符串,那就⽤ parseString
# dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
# parse 返回⼀个document
# 创建节点都是靠 parse返回的 dom_tree,这也很好理解,dom_tree其本⾝就是⼀个document对象,按照字⾯意思就是⽂档对象,xml就是⽂档
dom_tree = Document()
#因为没有⽂件,所以要创建⼀个,如果是已有xml⽂件,那就不⽤,直接 dom_tree = minidom.parse("l") root_node = dom_tree.documentElement #获取到根节点,下⾯的⼦节点都是挂载这个根节点下⾯,就是⼦节点的层级关系要弄好
root_node = ateElement("rootinfo")
dom_tree.appendChild(root_node)
#创建有属性的节点
info_node = ateElement("infodata")
info_node = ateElement("infodata")
#这个属性类似map中key,value
info_node.setAttribute("infoid", "57344")
# 把⼤节点info_node挂到根节点root_node下⾯
root_node.appendChild(info_node)
#创建节点
data = ateElement("data")
# 创建data的⼦节点,其内容创建为doccreateTextNode,根据名字,其也是⼀个节点 status_node = ateElement("status")
status_text = ateTextNode("1")
status_node.appendChild(status_text)
#把status_node 作为 data ⼦节点
data.appendChild(status_node)
title_node = ateElement("title")
title_text = ateTextNode("1111111")
title_node.appendChild(title_text)
data.appendChild(title_node)
time_node = ateElement("time")
title_node_text = ateTextNode("1596678431")
time_node.appendChild(title_node_text)
data.appendChild(time_node)
properties_node = ateElement("properties")
properties_node_text = ateTextNode("111111111111")
properties_node.appendChild(properties_node_text)
data.appendChild(properties_node)
info_node.appendChild(data)
#下⾯再创建⼀个data,只是类容不⼀样 /-----------------/
data = ateElement("data")
# 创建data的⼦节点,其内容创建为doccreateTextNode,根据名字,其也是⼀个节点 status_node = ateElement("status")
status_text = ateTextNode("9")
#⽂本⼦节点也要挂载节点下⾯,每个节点都需要挂在上⾯⼀个节点,⼀层⼀层的
status_node.appendChild(status_text)
# 把status_node 作为 data ⼦节点
data.appendChild(status_node)
title_node = ateElement("title")
title_text = ateTextNode("111111111111111111")
title_node.appendChild(title_text)
data.appendChild(title_node)
time_node = ateElement("time")
title_node_text = ateTextNode("1596678436")
time_node.appendChild(title_node_text)
data.appendChild(time_node)
properties_node = ateElement("properties")
properties_node_text = ateTextNode("11111111111111")
properties_node.appendChild(properties_node_text)
data.appendChild(properties_node)
info_node.appendChild(data)
with open(xml_path, 'w') as f:
# writexml(writer, indent="", addindent="", newl="", encoding=None),
# writer是⽂件对象, 必写参数,其余为可选参数
# indent是每个tag前填充的字符,如:' ',则表⽰每个tag前有两个空格
# addindent是每个⼦结点的缩近字符
# newl是每个tag后填充的字符,如:'\n',则表⽰每个tag后⾯有⼀个回车
dom_tree.writexml(f, addindent=' ',newl='\n',encoding='utf-8')
dom_tree.writexml(f, addindent=' ',newl='\n',encoding='utf-8')
def readXML(path):
#读取xml就可以⽤parse,读取上⾯保留的⽂件
#因为xml中有中⽂,不然直接⽤parse(path)
xml_content = open(path,'r').read()
xml_decoding_content = str(de('utf-8'),encoding='utf-8')
dom_tree = parseString(xml_decoding_content)
root_node = dom_tree.documentElement
#依次遍历打印节点
info_node = ElementsByTagName("infodata")
if root_node.hasAttribute("infoid"):
print("infoid: " + Attribute("infoid"))
#⽆论遍历哪个节点,都是通过根节点来查
#获取到所有节点为data的节点,xml中有两个,所以会有两个
data_node = ElementsByTagName("data")
for child_node in data_node:
#这⾥⾯[0]代表获取data节点下第⼀个status节点,有些有多个,后⾯.data则代表取节点内容
#因为ElementsByTagName("status")[0]是到status的节点,我们要去⽂本节点值,所以还要继续取第⼀个节点,即:childNodes[0],取值即da status = ElementsByTagName("status")[0].childNodes[0].data #ElementsByTagName("status")[0].childNodes[0].nodeValue 也可 print("status: " + status)
title = ElementsByTagName("title")[0].childNodes[0].data
print("title: " + title)
time = ElementsByTagName("time")[0].childNodes[0].data
print("status: " + time)
properties = ElementsByTagName("properties")[0].childNodes[0].data
print("status: " + properties)
#归结为就是,不管节点还是⽂本,其都是节点,想取其值,都要[0],因为默认是⼀个集合,不知道取第⼏个,所以要设置⼀下
def addAttribute2Xml(path):
# 上⾯的xml节点中已经有两个data了,我们再添加3个
data_list = [['13','1','1596679106','tedyt'],
['15','asdf','1596679505','sdffd'],
['19','sdfsdf','1596679726','sdfsdf。']]
# xml_content = open(path, 'r').read()
# xml_decoding_content = str(de('utf-8'), encoding='utf-8')
# dom_tree = parseString(xml_decoding_content)
dom_tree = parse(path)
root_node = dom_tree.documentElement
info_data_node = ElementsByTagName('infodata')[0]
# 此xml根节点是rootinfo,千万不要通过ElementsByTagName('rootinfo')[0],因为root_node就是rootinfo根节点,⼀旦这么操作,后⾯会出现异常情况 for data in data_list:
# # 创建data节点
# data_node = ateElement('data')
# # 创建status节点
# status_node = ateElement('status')
# status_node_text = ateTextNode(data[0])
# # status_node_text也是节点,所以要挂载在status节点下
# status_node.appendChild(status_node_text)
# data_node.appendChild(status_node)
#
# # 创建title节点
# title_node = ateElement('title')
# title_node_text = ateTextNode(data[1])
# title_node.appendChild(title_node_text)
# data_node.appendChild(title_node)
#
# # 创建time节点
# time_node = ateElement('title')
# time_node_text = ateTextNode(data[2])
# time_node.appendChild(time_node_text)
# data_node.appendChild(time_node)
#
# # 创建properties节点
# properties_node = ateElement('properties')
# properties_node_text = ateTextNode(data[3])
# properties_node_text = ateTextNode(data[3])
# properties_node.appendChild(properties_node_text)
# data_node.appendChild(properties_node)
#
# # 最后data_node要添加到infodata节点下
# # tab_text = ateTextNode('\n\t')
# # # info_node.appendChild(tab_text)
# info_node.appendChild(data_node)
# # 这⾥补充⼀下,之前由于解析的xml不是标准,然后添加元素进去后,格式不⼀样,主要就是⼀⾏空格不对,
# # 或者换⾏换了两⾏,这⾥可以通过在每个节点后加⼀个节点,这个节点就是换⾏,空格,如下:
# # tab_text = ateTextNode("\n\t") #换⾏加⼀个tab空格,这样后⾯⼀个节点加进来就直接前⾯空出⼀个tab空格 # # data_node.appendChild(tab_text) 添加到节点下
# # 这⾥路径既可以原来的,也可以新建⼀个xml,⽤原来就会覆盖
#
# with open(path, 'w') as f:
# # 缩进 - 换⾏ - 编码
# dom_tree.writexml(f,addindent=' ', encoding='utf-8')
# 原先格式是本⽂最开始那样,添加元素后,就为下⾯图这样,
# 所以我⽐较笨的办法是⾃⼰添加空格换⾏
two_empty = ' '
data_node = ateElement('data')
tab_text = ateTextNode('\n\t' + two_empty)
data_node.appendChild(tab_text)
# 创建status节点
status_node = ateElement('status')
status_node_text = ateTextNode(data[0])
# status_node_text也是节点,所以要挂载在status节点下
status_node.appendChild(status_node_text)
data_node.appendChild(status_node)
tab_text = ateTextNode('\n\t' + two_empty)
data_node.appendChild(tab_text)
# 创建title节点
title_node = ateElement('title')
title_node_text = ateTextNode(data[1])
title_node.appendChild(title_node_text)
data_node.appendChild(title_node)
tab_text = ateTextNode('\n\t' + two_empty)
data_node.appendChild(tab_text)
# 创建time节点
time_node = ateElement('title')
time_node_text = ateTextNode(data[2])
time_node.appendChild(time_node_text)
data_node.appendChild(time_node)
tab_text = ateTextNode('\n\t' + two_empty)
data_node.appendChild(tab_text)
# 创建properties节点
properties_node = ateElement('properties')
properties_node_text = ateTextNode(data[3])
properties_node.appendChild(properties_node_text)
data_node.appendChild(properties_node)
tab_text = ateTextNode('\n\t')
data_node.appendChild(tab_text)
tab_text = ateTextNode(two_empty)
info_data_node.appendChild(tab_text)
# 最后data_node要添加到infodata节点下
info_data_node.appendChild(data_node)
tab_text = ateTextNode('\n' + two_empty)
info_data_node.appendChild(tab_text)
tab_text = ateTextNode(two_empty)
root_node.appendChild(tab_text)
root_node.appendChild(info_data_node)
#这个是操作</root_infg>节点,最初是操作<root_info>节点 tab_text = ateTextNode('\n')
root_node.appendChild(tab_text)
with open(path, 'w') as f:
# 缩进 - 换⾏ - 编码
dom_tree.writexml(f,encoding='utf-8')
# with open(path, 'wb') as file:
# dom_tree.writexml(file)
if __name__ == "__main__":
path = "D:/l"
createXml(path)
readXML(path)
addAttribute2Xml(path)
# root_node -------------child_node_1
# |
# ---child_node_2 ------------chile_node_2_node_1 # | |
# ---child_node_3 ---chile_node_2_node_2 # |
# ---child_node_4
#generator xml
#modify xml
#xml add node
#xml add node and set tab or line break
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论