前言
近日工作中,遇到了一个场景———需要对xml文件中所有元素的文本内容替换为空,并导出为新的xml。手动替换着实是耗费时间,可以采用python minidom对xml读写进行批量操作。本文主要针对这样的简单的使用场景做分享。
PS||: xml长这样:
一年级
一班
35
王老师
二班
36
张老师
minidom 使用
为了达到前言中描述的目的,我们大概需要以下几个步骤:
读取res.xml文件
遍历获取含有文本内容的元素
替换文本内容为空
将新的xml写入到output.xml文件中
xml读取
在minidom中有两种读取xml的方式:
def parse(file, parser=None, bufsize=None) 读取xml文件或xml文件对象
def parseString(string, parser=None) 读取xml格式的字符串String
以下是使用示例
parse
import xml.dom.minidom
import os
import io
file = "F:\\tmp\\res.xml"
def read(filename):
domTree = xml.dom.minidom.parse(filename)
read(file)
解析res.xml,返回文件对象的节点list。
parseString
import xml.dom.minidom
xmlString = """
一年级
一班
35
王老师
二班
36
张老师
"""
domTree = xml.dom.minidom.parseString(xmlString)
解析xmlString字符串,返回文件对象的节点list。
遍历获取元素
对文件对象的节点判断是否有子元素,通过遍历、递归获取所有元素。
Y
N
node
has Child
get Element Node
get TEXT node
代码实现如下:
...
def getLeastNode(node):
flag = node.hasChildNodes()
if (flag):
for nodechild in node.childNodes:
if (nodechild.nodeType == 1):
print(nodechild.tagName)
getLeastNode(nodechild)
...
hasChildNodes为minidom提供的判断是否有子元素的方法,若有则返回真。
childNodes为当前元素的子节点list
在xml.dom中Node类将元素节点值定义为1 (ELEMENT_NODE=1)
在xml.dom中Node类将元素文本内容节点值定义为3 (TEXT_NODE=3)
替换元素的文本内容
minidom提供的Text类中有一个替换整个文本内容的方法:
def replaceWholeText(self, content)
示例如下:
...
def initValue(node):
if(node.data != "\n"):
node.replaceWholeText("");
...
Dom写入至新的xml中
minidom中提供了writexml,用于将xml文件对象写入到文件中。
def writexml(self, writer, indent="", addindent="", newl="")
示例如下:
...
outputfile = "F:\\tmp\\1607\\filepath2.xml";
f = open(outputfile,"w");
domTree.writexml(f, '', '\t', '\n');
...
domTree为读取的文件对象list
整体示例
'''
@Time : 2020/6/23 20:22
@Author : Silence
@File : .py
@Version: V1.0.0
@description: input a xml and output xml without node values
'''
# -*- coding: UTF-8 -*-
import xml.dom.minidom
import os
import io
import sys
# 初始化元素文本内容为空
def initValue(node):
if node.data is not '\n':
node.replaceWholeText("")
def getLeastNode(node):
if (node.hasChildNodes()):
for nodechild in node.childNodes:
if nodechild.nodeType is 1:
getLeastNode(nodechild)
# 依据xml示例特性,仅将有内容的节点文本内容进行替换。则子节点list长度为1,只含TEXT_NODE
elif nodechild.nodeType is 3 and node.childNodes.length is 1:
initValue(nodechild)
# 读取xml
def loadXml(filename):
domTree = xml.dom.minidom.parse(filename)
return domTree
# 写出xml
def dumpXml(xmlObj, filename):
with open(filename, 'w') as f:
xmlObj.writexml(f, '', '\t', '\n')
if __name__ == '__main__':
filepath = "F:\\tmp\\res.xml"
outputfile = "F:\\tmp\\output.xml"
obj = loadXml(filepath)
getLeastNode(obj.documentElement)
print(obj.toxml())
dumpXml(obj, outputfile)