Python处理XML格式数据的方法详解
作者:jasonblog 发布时间:2021-04-10 22:25:07
本文实例讲述了Python处理XML格式数据的方法。分享给大家供大家参考,具体如下:
这里的操作是基于Python3平台。
在使用Python处理XML的问题上,首先遇到的是编码问题。
Python并不支持gb2312,所以面对encoding="gb2312"的XML文件会出现错误。Python读取的文件本身的编码也可能导致抛出异常,这种情况下打开文件的时候就需要指定编码。此外就是XML中节点所包含的中文。
我这里呢,处理就比较简单了,只需要修改XML的encoding头部。
#!/usr/bin/env python
import os, sys
import re
def replaceXmlEncoding(filepath, oldEncoding='gb2312', newEncoding='utf-8'):
f = open(filepath, mode='r')
content = f.read()
content = re.sub(oldEncoding, newEncoding, content)
f.close()
f = open(filepath, mode='w')
f.write(content)
f.close()
if __name__ == "__main__":
replaceXmlEncoding('./ActivateAccount.xml')
接着是使用xml.etree.ElementTree来操作XML文件。
在一个类里面定义__call__函数可以使得该类可调用,比如下面代码的最后几行,在__main__函数中。这也很突出地体现了在Python的世界里,一切都是对象,包括对象本身 :)
一直觉得__main__函数用来测试真是蛮好用的。
#!/usr/bin/env python
import os, re
import xml.etree.ElementTree as etree
Locale_Path = "./locale.txt"
class xmlExtractor(object):
def __init__(self):
pass
def __call__(self, filepath):
retDict = {}
f = open(filepath, 'r')
Line = len(open(filepath, 'r').readlines())
retDict['Line'] = Line
tree = etree.parse(f)
root = tree.find("ResItem")
Id = root.get("ID")
retDict['Title'] = Id
resItemCnt = len(list(root.findall("ResItem"))) + 1
retDict['ResItemCount'] = resItemCnt
retDict['ChineseTip'] = 'None'
for child in root:
attrDict = child.attrib
keyword = "Name"
if(keyword in attrDict.keys() and attrDict['Name'] == "Caption"):
if len(child.attrib['Value']) > 1:
if child.attrib['Value'][0] == '~':
title = child.attrib['Value'][1:]
else:
title = child.attrib['Value'][0:]
#print(title)
chs = open(Locale_Path).read()
pattern = '<String id="' + title + '">[^>]+>'
m = re.search(pattern, chs)
if m != None:
realTitle = re.sub('<[^>]+>', '', m.group(0))
retDict['ChineseTip'] = realTitle
f.close()
return retDict
if __name__ == "__main__":
fo = xmlExtractor()
d = fo('./ActivateAccount.xml')
print(d)
最后,就是入口文件,导入上面两个文件,使用xml.dom和os.listdir来递归处理XML文件,并生成一个结果集。
一直觉得Python的UnboundLocalError错误挺有意思的,不知道是不是符号表的覆盖问题。
#!/usr/bin/env python
from xmlExtractor import *
from replaceXmlEncoding import *
from xml.dom import minidom,Node
doc = minidom.Document()
extractor = xmlExtractor()
totalLines = 0
totalResItemCnt = 0
totalXmlFileCnt = 0
totalErrorCnt = 0
errorFileList = []
xmlRoot = doc.createElement("XmlResourceFile")
doc.appendChild(xmlRoot)
def myWalkDir(level, path):
global doc, extractor, totalLines, totalResItemCnt, totalXmlFileCnt
global totalErrorCnt, errorFileList
global xmlRoot
for i in os.listdir(path):
if i[-3:] == 'xml':
totalXmlFileCnt += 1
try:
#先把xml的encoding由gb2312转换为utf-8
replaceXmlEncoding(path + '\\' + i)
#再提取xml文档中需要的信息
info = extractor(path + '\\' + i)
#在上述两行代码没有出现异常的基础上再创建节点
#print(info)
#print(type(i))
xmlNode = doc.createElement("XmlFile")
xmlRoot.appendChild(xmlNode)
xmlName = doc.createElement("Filename")
xmlName.setAttribute('Value', i)
#xmlName.appendChild(doc.createTextNode(i))
xmlNode.appendChild(xmlName)
filePath = doc.createElement("Filepath")
filePath.setAttribute('Value', path[34:])
#filePath.appendChild(doc.createTextNode(path[1:]))
xmlNode.appendChild(filePath)
titleNode = doc.createElement("Title")
titleNode.setAttribute('Value', str(info['Title']))
#titleNode.appendChild(doc.createTextNode(str(info['Title'])))
xmlNode.appendChild(titleNode)
chsNode = doc.createElement("ChineseTip")
chsNode.setAttribute('Value', str(info['ChineseTip']))
#chsNode.appendChild(doc.createTextNode(str(info['Chinese'])))
xmlNode.appendChild(chsNode)
resItemNode = doc.createElement("ResItemCount")
resItemNode.setAttribute('Value', str(info['ResItemCount']))
#resItemNode.appendChild(doc.createTextNode(str(info['ResItemCount'])))
xmlNode.appendChild(resItemNode)
lineNode = doc.createElement("LineCount")
lineNode.setAttribute('Value', str(info['Line']))
#lineNode.appendChild(doc.createTextNode(str(info['Line'])))
xmlNode.appendChild(lineNode)
descNode = doc.createElement("Description")
descNode.setAttribute('Value', '')
#descNode.appendChild(doc.createTextNode(''))
xmlNode.appendChild(descNode)
except Exception as errorDetail:
totalErrorCnt += 1
errorFileList.append(path + '\\' + i)
print(path + '\\' + i, errorDetail)
if os.path.isdir(path + '\\' + i):
myWalkDir(level+1, path + '\\' + i)
if __name__ == "__main__":
path = os.getcwd() + '\\themes'
myWalkDir(0, path)
print(totalXmlFileCnt, totalErrorCnt)
#print(doc.toprettyxml(indent = " "))
resultXml = open("./xmlResourceList.xml", "w")
resultXml.write(doc.toprettyxml(indent = " "))
resultXml.close()
PS:这里再为大家提供几款关于xml操作的在线工具供大家参考使用:
在线XML/JSON互相转换工具:
http://tools.jb51.net/code/xmljson
在线格式化XML/在线压缩XML:
http://tools.jb51.net/code/xmlformat
XML在线压缩/格式化工具:
http://tools.jb51.net/code/xml_format_compress
XML代码在线格式化美化工具:
http://tools.jb51.net/code/xmlcodeformat
希望本文所述对大家Python程序设计有所帮助。


猜你喜欢
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&
- 首先到官网下载python2.7.3版本,编译安装$wget http://www.python.org/ftp/python/2.7.3/
- 安装淘宝镜像:要安装Angular4。于是我对着一股浓郁口音的视频开启了Angular4安装之旅。那口音说了,ang哥乐4不是那么好装的,由
- 因为云服务器的centos是没有图形界面的,所以安装比较麻烦,刚好19c有本地rpm的安装方法,所以推荐用rpm安装。首先到官网下载rpm包
- 如下所示:fig.tight_layout()#调整整体空白 plt.subplots_adjust(wspace =0, hspace =
- 前言最近,我已经成功将我的个人网站从 Flask 迁移到 Django 了,最早接触 Django 的时候大概是在 4 年前,我记得那个时候
- 段时间作项目中,遇到使用视图的问题,以前的工作中很少遇到视图,认为直接用表就ok了,何须视图呢?下面我来讲述一下它的功用:以往当我们查询数据
- 一、Python 切片的一些用法alist = [3,4,5,6,7,9,11,13,15,17]print(alist[::]) # 返回
- XML是一项热门的技术。它之所以能够引起人们的兴趣,一个主要的原因在于它十分的简单,人们可以很容易地理解和使用它。每一个程序员都能轻易地看懂
- javascript函数的定义1:调用关键字function来构造,如:function distance(x1,x2,y1,y2){var
- 1、显式等待它指定要查找的节点,然后指定一个最长的等待时间,如果规定时间内加载出来了这个节点,就返回查找的节点;如果规定时间内没有加载出该节
- 前言又要过年了,今年你不妨自己写一段代码来抢回家的火车票,是不是很Cool。下面话不多说了,来一起看看详细的介绍吧。先准备好:12306网站
- mysql升级5.7版本以后,安全性大幅度上升。但是呢。。。带复杂的记不住。额额。。本来脑子就不好使,还记那么复杂,尤其是本地就更没必要,还
- 新闻系统,相册系统可以用用哦,简单实用,有兴趣的可以自己扩充!^_^相册截图:<?xml version="1.0"
- 最近需要做集团的SRC系统。暂无安全研发,所以只能找我这个小菜兼职开发。系统使用Django框架,在整个过程中,有许多奇特的需求。在某项需求
- 思路:遍历文件夹下面的文件夹如果文件夹名称等于".svn",则修改文件夹的属性(因为".svn"的文
- 本文实例为大家分享了OpenCV实现直线检测的具体代码,供大家参考,具体内容如下1 介绍本文主要介绍OpenCV自带的直线检测函数Hough
- 最近vue更新的2.0版本,唉,我是在2.0版本前学习的,现在更新了又要看一遍了,关键是我之前看了3个星期2.0就更新了,vux还没同步更新
- SHOW STATUS 直接在命令行下登陆MySQL运行SHOW STATUS;查询语句,详细如下图 同样的语句还有SHOW V
- 表达式的优先级表达式(Expression)是运算符(operator)和操作数(operand)所构成的序列代码段a = 1b = 2c