Python处理XML格式数据的方法详解


Posted in Python onMarch 21, 2017

本文实例讲述了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()
Python 相关文章推荐
Python中处理字符串之endswith()方法的使用简介
May 18 Python
python的多重继承的理解
Aug 06 Python
详解pandas的外部数据导入与常用方法
May 01 Python
Python中的几种矩阵乘法(小结)
Jul 10 Python
Django 缓存配置Redis使用详解
Jul 23 Python
python tkinter基本属性详解
Sep 16 Python
python-numpy-指数分布实例详解
Dec 07 Python
TensorFlow tensor的拼接实例
Jan 19 Python
什么是Python变量作用域
Jun 03 Python
Python常用扩展插件使用教程解析
Nov 02 Python
Python爬虫后获取重定向url的两种方法
Jan 19 Python
pandas提升计算效率的一些方法汇总
May 30 Python
Python做简单的字符串匹配详解
Mar 21 #Python
Python 转义字符详细介绍
Mar 21 #Python
python 迭代器和iter()函数详解及实例
Mar 21 #Python
浅谈五大Python Web框架
Mar 20 #Python
python rsa 加密解密
Mar 20 #Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 #Python
python list排序的两种方法及实例讲解
Mar 20 #Python
You might like
CI框架的安全性分析
2016/05/18 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
使两个iframe的高度与内容自适应,且相等
2006/11/20 Javascript
使用jQuery轻松实现Ajax的实例代码
2010/08/16 Javascript
Jquery拖拽并简单保存的实现代码
2010/11/28 Javascript
js中的string.format函数代码
2020/08/11 Javascript
如何设置iframe高度自适应在跨域情况下的可用方法
2013/09/06 Javascript
javascript常见数据验证插件大全
2015/08/03 Javascript
js实现表单多按钮提交action的处理方法
2015/10/24 Javascript
jQuery仿IOS弹出框插件
2017/02/18 Javascript
Angular 4依赖注入学习教程之简介(一)
2017/06/04 Javascript
vue 项目如何引入微信sdk接口的方法
2017/12/18 Javascript
vue2.0+vue-dplayer实现hls播放的示例
2018/03/02 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
ES6使用export和import实现模块化的方法
2018/09/10 Javascript
详解react-refetch的使用小例子
2019/02/15 Javascript
Vue 实现从小到大的横向滑动效果详解
2019/10/16 Javascript
vue-路由精讲 二级路由和三级路由的作用
2020/08/06 Javascript
[01:38]【DOTA2亚洲邀请赛】Sumail——梦开始的地方
2017/03/03 DOTA
[52:05]EG vs OG 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
Python 列表list使用介绍
2014/11/30 Python
python实现简单温度转换的方法
2015/03/13 Python
python代码 输入数字使其反向输出的方法
2018/12/22 Python
python 实现矩阵按对角线打印
2019/11/29 Python
Python3实现将一维数组按标准长度分隔为二维数组
2019/11/29 Python
Python实现子类调用父类的初始化实例
2020/03/12 Python
Pytorch1.5.1版本安装的方法步骤
2020/12/31 Python
Python扫描端口的实现
2021/01/25 Python
高中生毕业自我鉴定范文
2013/12/22 职场文书
质量承诺书格式
2014/05/20 职场文书
学校安全生产承诺书
2014/05/23 职场文书
新生开学寄语大全
2015/05/28 职场文书
2015年小学师德师风建设工作总结
2015/10/23 职场文书
入党申请书格式
2019/06/20 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android